Import FreeBSD/arm kernel bits.

It only supports sa1110 (on simics) right now, but xscale support should come
soon.
Some of the initial work has been provided by :
Stephane Potvin <sepotvin at videotron.ca>
Most of this comes from NetBSD.
This commit is contained in:
Olivier Houchard 2004-05-14 11:46:45 +00:00
parent 0025fb0f4f
commit 6fc729af63
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=129198
124 changed files with 30630 additions and 69 deletions

98
sys/arm/arm/autoconf.c Normal file
View File

@ -0,0 +1,98 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
* from: FreeBSD: src/sys/i386/i386/autoconf.c,v 1.156
*/
/*
* Setup the system to run on the current machine.
*
* Configure() is called at boot time and initializes the vba
* device tables and the memory controller monitoring. Available
* devices are determined (from possibilities mentioned in ioconf.c),
* and the drivers are initialized.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/disklabel.h>
#include <sys/reboot.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/cons.h>
static void configure_first (void *);
static void configure (void *);
static void configure_final (void *);
SYSINIT(configure1, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure_first, NULL);
/* SI_ORDER_SECOND is hookable */
SYSINIT(configure2, SI_SUB_CONFIGURE, SI_ORDER_THIRD, configure, NULL);
/* SI_ORDER_MIDDLE is hookable */
SYSINIT(configure3, SI_SUB_CONFIGURE, SI_ORDER_ANY, configure_final, NULL);
device_t nexus_dev;
/*
* Determine i/o configuration for a machine.
*/
static void
configure_first(void *dummy)
{
}
static void
configure(void *dummy)
{
device_add_child(root_bus, "nexus", 0);
root_bus_configure();
cold = 0;
cninit_finish();
}
static void
configure_final(void *dummy)
{
}

273
sys/arm/arm/bcopy_page.S Normal file
View File

@ -0,0 +1,273 @@
/* $NetBSD: bcopy_page.S,v 1.7 2003/10/13 21:03:13 scw Exp $ */
/*
* Copyright (c) 1995 Scott Stevens
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Scott Stevens.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RiscBSD kernel project
*
* bcopy_page.S
*
* page optimised bcopy and bzero routines
*
* Created : 08/04/95
*/
#include <machine/asm.h>
#include <machine/param.h>
__FBSDID("$FreeBSD$");
#ifndef __XSCALE__
/* #define BIG_LOOPS */
/*
* bcopy_page(src, dest)
*
* Optimised copy page routine.
*
* On entry:
* r0 - src address
* r1 - dest address
*
* Requires:
* number of bytes per page (PAGE_SIZE) is a multiple of 512 (BIG_LOOPS), 128
* otherwise.
*/
#define CHUNK_SIZE 32
#define PREFETCH_FIRST_CHUNK /* nothing */
#define PREFETCH_NEXT_CHUNK /* nothing */
#ifndef COPY_CHUNK
#define COPY_CHUNK \
PREFETCH_NEXT_CHUNK ; \
ldmia r0!, {r3-r8,ip,lr} ; \
stmia r1!, {r3-r8,ip,lr}
#endif /* ! COPY_CHUNK */
#ifndef SAVE_REGS
#define SAVE_REGS stmfd sp!, {r4-r8, lr}
#define RESTORE_REGS ldmfd sp!, {r4-r8, pc}
#endif
ENTRY(bcopy_page)
PREFETCH_FIRST_CHUNK
SAVE_REGS
#ifdef BIG_LOOPS
mov r2, #(PAGE_SIZE >> 9)
#else
mov r2, #(PAGE_SIZE >> 7)
#endif
1:
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
#ifdef BIG_LOOPS
/* There is little point making the loop any larger; unless we are
running with the cache off, the load/store overheads will
completely dominate this loop. */
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
COPY_CHUNK
#endif
subs r2, r2, #1
bne 1b
RESTORE_REGS /* ...and return. */
/*
* bzero_page(dest)
*
* Optimised zero page routine.
*
* On entry:
* r0 - dest address
*
* Requires:
* number of bytes per page (PAGE_SIZE) is a multiple of 512 (BIG_LOOPS), 128
* otherwise
*/
ENTRY(bzero_page)
stmfd sp!, {r4-r8, lr}
#ifdef BIG_LOOPS
mov r2, #(PAGE_SIZE >> 9)
#else
mov r2, #(PAGE_SIZE >> 7)
#endif
mov r3, #0
mov r4, #0
mov r5, #0
mov r6, #0
mov r7, #0
mov r8, #0
mov ip, #0
mov lr, #0
1:
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
#ifdef BIG_LOOPS
/* There is little point making the loop any larger; unless we are
running with the cache off, the load/store overheads will
completely dominate this loop. */
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
stmia r0!, {r3-r8,ip,lr}
#endif
subs r2, r2, #1
bne 1b
ldmfd sp!, {r4-r8, pc}
#else /* __XSCALE__ */
/*
* XSCALE version of bcopy_page
*/
ENTRY(bcopy_page)
pld [r0]
stmfd sp!, {r4, r5}
mov ip, #32
ldr r2, [r0], #0x04 /* 0x00 */
ldr r3, [r0], #0x04 /* 0x04 */
1: pld [r0, #0x18] /* Prefetch 0x20 */
ldr r4, [r0], #0x04 /* 0x08 */
ldr r5, [r0], #0x04 /* 0x0c */
strd r2, [r1], #0x08
ldr r2, [r0], #0x04 /* 0x10 */
ldr r3, [r0], #0x04 /* 0x14 */
strd r4, [r1], #0x08
ldr r4, [r0], #0x04 /* 0x18 */
ldr r5, [r0], #0x04 /* 0x1c */
strd r2, [r1], #0x08
ldr r2, [r0], #0x04 /* 0x20 */
ldr r3, [r0], #0x04 /* 0x24 */
pld [r0, #0x18] /* Prefetch 0x40 */
strd r4, [r1], #0x08
ldr r4, [r0], #0x04 /* 0x28 */
ldr r5, [r0], #0x04 /* 0x2c */
strd r2, [r1], #0x08
ldr r2, [r0], #0x04 /* 0x30 */
ldr r3, [r0], #0x04 /* 0x34 */
strd r4, [r1], #0x08
ldr r4, [r0], #0x04 /* 0x38 */
ldr r5, [r0], #0x04 /* 0x3c */
strd r2, [r1], #0x08
ldr r2, [r0], #0x04 /* 0x40 */
ldr r3, [r0], #0x04 /* 0x44 */
pld [r0, #0x18] /* Prefetch 0x60 */
strd r4, [r1], #0x08
ldr r4, [r0], #0x04 /* 0x48 */
ldr r5, [r0], #0x04 /* 0x4c */
strd r2, [r1], #0x08
ldr r2, [r0], #0x04 /* 0x50 */
ldr r3, [r0], #0x04 /* 0x54 */
strd r4, [r1], #0x08
ldr r4, [r0], #0x04 /* 0x58 */
ldr r5, [r0], #0x04 /* 0x5c */
strd r2, [r1], #0x08
ldr r2, [r0], #0x04 /* 0x60 */
ldr r3, [r0], #0x04 /* 0x64 */
pld [r0, #0x18] /* Prefetch 0x80 */
strd r4, [r1], #0x08
ldr r4, [r0], #0x04 /* 0x68 */
ldr r5, [r0], #0x04 /* 0x6c */
strd r2, [r1], #0x08
ldr r2, [r0], #0x04 /* 0x70 */
ldr r3, [r0], #0x04 /* 0x74 */
strd r4, [r1], #0x08
ldr r4, [r0], #0x04 /* 0x78 */
ldr r5, [r0], #0x04 /* 0x7c */
strd r2, [r1], #0x08
subs ip, ip, #0x01
ldrgt r2, [r0], #0x04 /* 0x80 */
ldrgt r3, [r0], #0x04 /* 0x84 */
strd r4, [r1], #0x08
bgt 1b
ldmfd sp!, {r4, r5}
mov pc, lr
/*
* XSCALE version of bzero_page
*/
ENTRY(bzero_page)
mov r1, #PAGE_SIZE
mov r2, #0
mov r3, #0
1: strd r2, [r0], #8 /* 32 */
strd r2, [r0], #8
strd r2, [r0], #8
strd r2, [r0], #8
strd r2, [r0], #8 /* 64 */
strd r2, [r0], #8
strd r2, [r0], #8
strd r2, [r0], #8
strd r2, [r0], #8 /* 96 */
strd r2, [r0], #8
strd r2, [r0], #8
strd r2, [r0], #8
strd r2, [r0], #8 /* 128 */
strd r2, [r0], #8
strd r2, [r0], #8
strd r2, [r0], #8
subs r1, r1, #128
bne 1b
mov pc, lr
#endif /* __XSCALE__ */

810
sys/arm/arm/bcopyinout.S Normal file
View File

@ -0,0 +1,810 @@
/* $NetBSD: bcopyinout.S,v 1.11 2003/10/13 21:22:40 scw Exp $ */
/*
* Copyright (c) 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Allen Briggs for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "assym.s"
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
#ifdef __XSCALE__
#include "bcopyinout_xscale.S"
#else
.text
.align 0
#ifdef MULTIPROCESSOR
.Lcpu_info:
.word _C_LABEL(cpu_info)
#else
.Lcurpcb:
.word _C_LABEL(__pcpu) + PC_CURPCB
#endif
#define SAVE_REGS stmfd sp!, {r4-r11}
#define RESTORE_REGS ldmfd sp!, {r4-r11}
#if defined(__XSCALE__)
#define HELLOCPP #
#define PREFETCH(rx,o) pld [ rx , HELLOCPP (o) ]
#else
#define PREFETCH(rx,o)
#endif
/*
* r0 = user space address
* r1 = kernel space address
* r2 = length
*
* Copies bytes from user space to kernel space
*
* We save/restore r4-r11:
* r4-r11 are scratch
*/
ENTRY(copyin)
/* Quick exit if length is zero */
teq r2, #0
moveq r0, #0
moveq pc, lr
SAVE_REGS
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0-r2, r14}
bl _C_LABEL(cpu_number)
ldr r4, .Lcpu_info
ldr r4, [r4, r0, lsl #2]
ldr r4, [r4, #CI_CURPCB]
ldmfd sp!, {r0-r2, r14}
#else
ldr r4, .Lcurpcb
ldr r4, [r4]
#endif
ldr r5, [r4, #PCB_ONFAULT]
adr r3, .Lcopyfault
str r3, [r4, #PCB_ONFAULT]
PREFETCH(r0, 0)
PREFETCH(r1, 0)
/*
* If not too many bytes, take the slow path.
*/
cmp r2, #0x08
blt .Licleanup
/*
* Align destination to word boundary.
*/
and r6, r1, #0x3
ldr pc, [pc, r6, lsl #2]
b .Lialend
.word .Lialend
.word .Lial3
.word .Lial2
.word .Lial1
.Lial3: ldrbt r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lial2: ldrbt r7, [r0], #1
sub r2, r2, #1
strb r7, [r1], #1
.Lial1: ldrbt r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lialend:
/*
* If few bytes left, finish slow.
*/
cmp r2, #0x08
blt .Licleanup
/*
* If source is not aligned, finish slow.
*/
ands r3, r0, #0x03
bne .Licleanup
cmp r2, #0x60 /* Must be > 0x5f for unrolled cacheline */
blt .Licleanup8
/*
* Align destination to cacheline boundary.
* If source and destination are nicely aligned, this can be a big
* win. If not, it's still cheaper to copy in groups of 32 even if
* we don't get the nice cacheline alignment.
*/
and r6, r1, #0x1f
ldr pc, [pc, r6]
b .Licaligned
.word .Licaligned
.word .Lical28
.word .Lical24
.word .Lical20
.word .Lical16
.word .Lical12
.word .Lical8
.word .Lical4
.Lical28:ldrt r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lical24:ldrt r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lical20:ldrt r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lical16:ldrt r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lical12:ldrt r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lical8:ldrt r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lical4:ldrt r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
/*
* We start with > 0x40 bytes to copy (>= 0x60 got us into this
* part of the code, and we may have knocked that down by as much
* as 0x1c getting aligned).
*
* This loop basically works out to:
* do {
* prefetch-next-cacheline(s)
* bytes -= 0x20;
* copy cacheline
* } while (bytes >= 0x40);
* bytes -= 0x20;
* copy cacheline
*/
.Licaligned:
PREFETCH(r0, 32)
PREFETCH(r1, 32)
sub r2, r2, #0x20
/* Copy a cacheline */
ldrt r10, [r0], #4
ldrt r11, [r0], #4
ldrt r6, [r0], #4
ldrt r7, [r0], #4
ldrt r8, [r0], #4
ldrt r9, [r0], #4
stmia r1!, {r10-r11}
ldrt r10, [r0], #4
ldrt r11, [r0], #4
stmia r1!, {r6-r11}
cmp r2, #0x40
bge .Licaligned
sub r2, r2, #0x20
/* Copy a cacheline */
ldrt r10, [r0], #4
ldrt r11, [r0], #4
ldrt r6, [r0], #4
ldrt r7, [r0], #4
ldrt r8, [r0], #4
ldrt r9, [r0], #4
stmia r1!, {r10-r11}
ldrt r10, [r0], #4
ldrt r11, [r0], #4
stmia r1!, {r6-r11}
cmp r2, #0x08
blt .Liprecleanup
.Licleanup8:
ldrt r8, [r0], #4
ldrt r9, [r0], #4
sub r2, r2, #8
stmia r1!, {r8, r9}
cmp r2, #8
bge .Licleanup8
.Liprecleanup:
/*
* If we're done, bail.
*/
cmp r2, #0
beq .Lout
.Licleanup:
and r6, r2, #0x3
ldr pc, [pc, r6, lsl #2]
b .Licend
.word .Lic4
.word .Lic1
.word .Lic2
.word .Lic3
.Lic4: ldrbt r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lic3: ldrbt r7, [r0], #1
sub r2, r2, #1
strb r7, [r1], #1
.Lic2: ldrbt r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lic1: ldrbt r7, [r0], #1
subs r2, r2, #1
strb r7, [r1], #1
.Licend:
bne .Licleanup
.Liout:
mov r0, #0
str r5, [r4, #PCB_ONFAULT]
RESTORE_REGS
mov pc, lr
.Lcopyfault:
mov r0, #14 /* EFAULT */
str r5, [r4, #PCB_ONFAULT]
RESTORE_REGS
mov pc, lr
/*
* r0 = kernel space address
* r1 = user space address
* r2 = length
*
* Copies bytes from kernel space to user space
*
* We save/restore r4-r11:
* r4-r11 are scratch
*/
ENTRY(copyout)
/* Quick exit if length is zero */
teq r2, #0
moveq r0, #0
moveq pc, lr
SAVE_REGS
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0-r2, r14}
bl _C_LABEL(cpu_number)
ldr r4, .Lcpu_info
ldr r4, [r4, r0, lsl #2]
ldr r4, [r4, #CI_CURPCB]
ldmfd sp!, {r0-r2, r14}
#else
ldr r4, .Lcurpcb
ldr r4, [r4]
#endif
ldr r5, [r4, #PCB_ONFAULT]
adr r3, .Lcopyfault
str r3, [r4, #PCB_ONFAULT]
PREFETCH(r0, 0)
PREFETCH(r1, 0)
/*
* If not too many bytes, take the slow path.
*/
cmp r2, #0x08
blt .Lcleanup
/*
* Align destination to word boundary.
*/
and r6, r1, #0x3
ldr pc, [pc, r6, lsl #2]
b .Lalend
.word .Lalend
.word .Lal3
.word .Lal2
.word .Lal1
.Lal3: ldrb r6, [r0], #1
sub r2, r2, #1
strbt r6, [r1], #1
.Lal2: ldrb r7, [r0], #1
sub r2, r2, #1
strbt r7, [r1], #1
.Lal1: ldrb r6, [r0], #1
sub r2, r2, #1
strbt r6, [r1], #1
.Lalend:
/*
* If few bytes left, finish slow.
*/
cmp r2, #0x08
blt .Lcleanup
/*
* If source is not aligned, finish slow.
*/
ands r3, r0, #0x03
bne .Lcleanup
cmp r2, #0x60 /* Must be > 0x5f for unrolled cacheline */
blt .Lcleanup8
/*
* Align source & destination to cacheline boundary.
*/
and r6, r1, #0x1f
ldr pc, [pc, r6]
b .Lcaligned
.word .Lcaligned
.word .Lcal28
.word .Lcal24
.word .Lcal20
.word .Lcal16
.word .Lcal12
.word .Lcal8
.word .Lcal4
.Lcal28:ldr r6, [r0], #4
sub r2, r2, #4
strt r6, [r1], #4
.Lcal24:ldr r7, [r0], #4
sub r2, r2, #4
strt r7, [r1], #4
.Lcal20:ldr r6, [r0], #4
sub r2, r2, #4
strt r6, [r1], #4
.Lcal16:ldr r7, [r0], #4
sub r2, r2, #4
strt r7, [r1], #4
.Lcal12:ldr r6, [r0], #4
sub r2, r2, #4
strt r6, [r1], #4
.Lcal8: ldr r7, [r0], #4
sub r2, r2, #4
strt r7, [r1], #4
.Lcal4: ldr r6, [r0], #4
sub r2, r2, #4
strt r6, [r1], #4
/*
* We start with > 0x40 bytes to copy (>= 0x60 got us into this
* part of the code, and we may have knocked that down by as much
* as 0x1c getting aligned).
*
* This loop basically works out to:
* do {
* prefetch-next-cacheline(s)
* bytes -= 0x20;
* copy cacheline
* } while (bytes >= 0x40);
* bytes -= 0x20;
* copy cacheline
*/
.Lcaligned:
PREFETCH(r0, 32)
PREFETCH(r1, 32)
sub r2, r2, #0x20
/* Copy a cacheline */
ldmia r0!, {r6-r11}
strt r6, [r1], #4
strt r7, [r1], #4
ldmia r0!, {r6-r7}
strt r8, [r1], #4
strt r9, [r1], #4
strt r10, [r1], #4
strt r11, [r1], #4
strt r6, [r1], #4
strt r7, [r1], #4
cmp r2, #0x40
bge .Lcaligned
sub r2, r2, #0x20
/* Copy a cacheline */
ldmia r0!, {r6-r11}
strt r6, [r1], #4
strt r7, [r1], #4
ldmia r0!, {r6-r7}
strt r8, [r1], #4
strt r9, [r1], #4
strt r10, [r1], #4
strt r11, [r1], #4
strt r6, [r1], #4
strt r7, [r1], #4
cmp r2, #0x08
blt .Lprecleanup
.Lcleanup8:
ldmia r0!, {r8-r9}
sub r2, r2, #8
strt r8, [r1], #4
strt r9, [r1], #4
cmp r2, #8
bge .Lcleanup8
.Lprecleanup:
/*
* If we're done, bail.
*/
cmp r2, #0
beq .Lout
.Lcleanup:
and r6, r2, #0x3
ldr pc, [pc, r6, lsl #2]
b .Lcend
.word .Lc4
.word .Lc1
.word .Lc2
.word .Lc3
.Lc4: ldrb r6, [r0], #1
sub r2, r2, #1
strbt r6, [r1], #1
.Lc3: ldrb r7, [r0], #1
sub r2, r2, #1
strbt r7, [r1], #1
.Lc2: ldrb r6, [r0], #1
sub r2, r2, #1
strbt r6, [r1], #1
.Lc1: ldrb r7, [r0], #1
subs r2, r2, #1
strbt r7, [r1], #1
.Lcend:
bne .Lcleanup
.Lout:
mov r0, #0
str r5, [r4, #PCB_ONFAULT]
RESTORE_REGS
mov pc, lr
/*
* r0 = kernel space source address
* r1 = kernel space destination address
* r2 = length
*
* Copies bytes from kernel space to kernel space, aborting on page fault
*
* Copy of copyout, but without the ldrt/strt instructions.
*/
ENTRY(kcopy)
/* Quick exit if length is zero */
teq r2, #0
moveq r0, #0
moveq pc, lr
SAVE_REGS
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0-r2, r14}
bl _C_LABEL(cpu_number)
ldr r4, .Lcpu_info
ldr r4, [r4, r0, lsl #2]
ldr r4, [r4, #CI_CURPCB]
ldmfd sp!, {r0-r2, r14}
#else
ldr r4, .Lcurpcb
ldr r4, [r4]
#endif
ldr r5, [r4, #PCB_ONFAULT]
adr r3, .Lcopyfault
str r3, [r4, #PCB_ONFAULT]
PREFETCH(r0, 0)
PREFETCH(r1, 0)
/*
* If not too many bytes, take the slow path.
*/
cmp r2, #0x08
blt .Lkcleanup
/*
* Align destination to word boundary.
*/
and r6, r1, #0x3
ldr pc, [pc, r6, lsl #2]
b .Lkalend
.word .Lkalend
.word .Lkal3
.word .Lkal2
.word .Lkal1
.Lkal3: ldrb r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lkal2: ldrb r7, [r0], #1
sub r2, r2, #1
strb r7, [r1], #1
.Lkal1: ldrb r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lkalend:
/*
* If few bytes left, finish slow.
*/
cmp r2, #0x08
blt .Lkcleanup
/*
* If source is not aligned, finish slow.
*/
ands r3, r0, #0x03
bne .Lkcleanup
cmp r2, #0x60 /* Must be > 0x5f for unrolled cacheline */
blt .Lkcleanup8
/*
* Align source & destination to cacheline boundary.
*/
and r6, r1, #0x1f
ldr pc, [pc, r6]
b .Lkcaligned
.word .Lkcaligned
.word .Lkcal28
.word .Lkcal24
.word .Lkcal20
.word .Lkcal16
.word .Lkcal12
.word .Lkcal8
.word .Lkcal4
.Lkcal28:ldr r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lkcal24:ldr r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lkcal20:ldr r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lkcal16:ldr r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lkcal12:ldr r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
.Lkcal8:ldr r7, [r0], #4
sub r2, r2, #4
str r7, [r1], #4
.Lkcal4:ldr r6, [r0], #4
sub r2, r2, #4
str r6, [r1], #4
/*
* We start with > 0x40 bytes to copy (>= 0x60 got us into this
* part of the code, and we may have knocked that down by as much
* as 0x1c getting aligned).
*
* This loop basically works out to:
* do {
* prefetch-next-cacheline(s)
* bytes -= 0x20;
* copy cacheline
* } while (bytes >= 0x40);
* bytes -= 0x20;
* copy cacheline
*/
.Lkcaligned:
PREFETCH(r0, 32)
PREFETCH(r1, 32)
sub r2, r2, #0x20
/* Copy a cacheline */
ldmia r0!, {r6-r11}
stmia r1!, {r6, r7}
ldmia r0!, {r6, r7}
stmia r1!, {r8-r11}
stmia r1!, {r6, r7}
cmp r2, #0x40
bge .Lkcaligned
sub r2, r2, #0x20
/* Copy a cacheline */
ldmia r0!, {r6-r11}
stmia r1!, {r6-r7}
ldmia r0!, {r6-r7}
stmia r1!, {r8-r11}
stmia r1!, {r6-r7}
cmp r2, #0x08
blt .Lkprecleanup
.Lkcleanup8:
ldmia r0!, {r8-r9}
sub r2, r2, #8
stmia r1!, {r8-r9}
cmp r2, #8
bge .Lkcleanup8
.Lkprecleanup:
/*
* If we're done, bail.
*/
cmp r2, #0
beq .Lkout
.Lkcleanup:
and r6, r2, #0x3
ldr pc, [pc, r6, lsl #2]
b .Lkcend
.word .Lkc4
.word .Lkc1
.word .Lkc2
.word .Lkc3
.Lkc4: ldrb r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lkc3: ldrb r7, [r0], #1
sub r2, r2, #1
strb r7, [r1], #1
.Lkc2: ldrb r6, [r0], #1
sub r2, r2, #1
strb r6, [r1], #1
.Lkc1: ldrb r7, [r0], #1
subs r2, r2, #1
strb r7, [r1], #1
.Lkcend:
bne .Lkcleanup
.Lkout:
mov r0, #0
str r5, [r4, #PCB_ONFAULT]
RESTORE_REGS
mov pc, lr
#endif /* !__XSCALE__ */
/*
* int badaddr_read_1(const uint8_t *src, uint8_t *dest)
*
* Copies a single 8-bit value from src to dest, returning 0 on success,
* else EFAULT if a page fault occurred.
*/
ENTRY(badaddr_read_1)
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0-r1, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0-r1, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
ldr ip, [r2, #PCB_ONFAULT]
adr r3, 1f
str r3, [r2, #PCB_ONFAULT]
nop
nop
nop
ldrb r3, [r0]
nop
nop
nop
strb r3, [r1]
mov r0, #0 /* No fault */
1: str ip, [r2, #PCB_ONFAULT]
mov pc, lr
/*
* int badaddr_read_2(const uint16_t *src, uint16_t *dest)
*
* Copies a single 16-bit value from src to dest, returning 0 on success,
* else EFAULT if a page fault occurred.
*/
ENTRY(badaddr_read_2)
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0-r1, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0-r1, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
ldr ip, [r2, #PCB_ONFAULT]
adr r3, 1f
str r3, [r2, #PCB_ONFAULT]
nop
nop
nop
ldrh r3, [r0]
nop
nop
nop
strh r3, [r1]
mov r0, #0 /* No fault */
1: str ip, [r2, #PCB_ONFAULT]
mov pc, lr
/*
* int badaddr_read_4(const uint32_t *src, uint32_t *dest)
*
* Copies a single 32-bit value from src to dest, returning 0 on success,
* else EFAULT if a page fault occurred.
*/
ENTRY(badaddr_read_4)
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0-r1, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0-r1, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
ldr ip, [r2, #PCB_ONFAULT]
adr r3, 1f
str r3, [r2, #PCB_ONFAULT]
nop
nop
nop
ldr r3, [r0]
nop
nop
nop
str r3, [r1]
mov r0, #0 /* No fault */
1: str ip, [r2, #PCB_ONFAULT]
mov pc, lr

File diff suppressed because it is too large Load Diff

587
sys/arm/arm/blockio.S Normal file
View File

@ -0,0 +1,587 @@
/* $NetBSD: blockio.S,v 1.5 2002/08/15 01:38:16 briggs Exp $ */
/*
* Copyright (c) 2001 Ben Harris.
* Copyright (c) 1994 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* blockio.S
*
* optimised block read/write from/to IO routines.
*
* Created : 08/10/94
* Modified : 22/01/99 -- R.Earnshaw
* Faster, and small tweaks for StrongARM
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* Read bytes from an I/O address into a block of memory
*
* r0 = address to read from (IO)
* r1 = address to write to (memory)
* r2 = length
*/
/* This code will look very familiar if you've read _memcpy(). */
ENTRY(read_multi_1)
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
subs r2, r2, #4 /* r2 = length - 4 */
blt .Lrm1_l4 /* less than 4 bytes */
ands r12, r1, #3
beq .Lrm1_main /* aligned destination */
rsb r12, r12, #4
cmp r12, #2
ldrb r3, [r0]
strb r3, [r1], #1
ldrgeb r3, [r0]
strgeb r3, [r1], #1
ldrgtb r3, [r0]
strgtb r3, [r1], #1
subs r2, r2, r12
blt .Lrm1_l4
.Lrm1_main:
.Lrm1loop:
ldrb r3, [r0]
ldrb r12, [r0]
orr r3, r3, r12, lsl #8
ldrb r12, [r0]
orr r3, r3, r12, lsl #16
ldrb r12, [r0]
orr r3, r3, r12, lsl #24
str r3, [r1], #4
subs r2, r2, #4
bge .Lrm1loop
.Lrm1_l4:
adds r2, r2, #4 /* r2 = length again */
ldmeqdb fp, {fp, sp, pc}
moveq pc, r14
cmp r2, #2
ldrb r3, [r0]
strb r3, [r1], #1
ldrgeb r3, [r0]
strgeb r3, [r1], #1
ldrgtb r3, [r0]
strgtb r3, [r1], #1
ldmdb fp, {fp, sp, pc}
/*
* Write bytes to an I/O address from a block of memory
*
* r0 = address to write to (IO)
* r1 = address to read from (memory)
* r2 = length
*/
/* This code will look very familiar if you've read _memcpy(). */
ENTRY(write_multi_1)
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
subs r2, r2, #4 /* r2 = length - 4 */
blt .Lwm1_l4 /* less than 4 bytes */
ands r12, r1, #3
beq .Lwm1_main /* aligned source */
rsb r12, r12, #4
cmp r12, #2
ldrb r3, [r1], #1
strb r3, [r0]
ldrgeb r3, [r1], #1
strgeb r3, [r0]
ldrgtb r3, [r1], #1
strgtb r3, [r0]
subs r2, r2, r12
blt .Lwm1_l4
.Lwm1_main:
.Lwm1loop:
ldr r3, [r1], #4
strb r3, [r0]
mov r3, r3, lsr #8
strb r3, [r0]
mov r3, r3, lsr #8
strb r3, [r0]
mov r3, r3, lsr #8
strb r3, [r0]
subs r2, r2, #4
bge .Lwm1loop
.Lwm1_l4:
adds r2, r2, #4 /* r2 = length again */
ldmeqdb fp, {fp, sp, pc}
cmp r2, #2
ldrb r3, [r1], #1
strb r3, [r0]
ldrgeb r3, [r1], #1
strgeb r3, [r0]
ldrgtb r3, [r1], #1
strgtb r3, [r0]
ldmdb fp, {fp, sp, pc}
/*
* Reads short ints (16 bits) from an I/O address into a block of memory
*
* r0 = address to read from (IO)
* r1 = address to write to (memory)
* r2 = length
*/
ENTRY(insw)
/* Make sure that we have a positive length */
cmp r2, #0x00000000
movle pc, lr
/* If the destination address and the size is word aligned, do it fast */
tst r2, #0x00000001
tsteq r1, #0x00000003
beq .Lfastinsw
/* Non aligned insw */
.Linswloop:
ldr r3, [r0]
subs r2, r2, #0x00000001 /* Loop test in load delay slot */
strb r3, [r1], #0x0001
mov r3, r3, lsr #8
strb r3, [r1], #0x0001
bgt .Linswloop
mov pc, lr
/* Word aligned insw */
.Lfastinsw:
.Lfastinswloop:
ldr r3, [r0, #0x0002] /* take advantage of nonaligned
* word accesses */
ldr ip, [r0]
mov r3, r3, lsr #16 /* Put the two shorts together */
orr r3, r3, ip, lsl #16
str r3, [r1], #0x0004 /* Store */
subs r2, r2, #0x00000002 /* Next */
bgt .Lfastinswloop
mov pc, lr
/*
* Writes short ints (16 bits) from a block of memory to an I/O address
*
* r0 = address to write to (IO)
* r1 = address to read from (memory)
* r2 = length
*/
ENTRY(outsw)
/* Make sure that we have a positive length */
cmp r2, #0x00000000
movle pc, lr
/* If the destination address and the size is word aligned, do it fast */
tst r2, #0x00000001
tsteq r1, #0x00000003
beq .Lfastoutsw
/* Non aligned outsw */
.Loutswloop:
ldrb r3, [r1], #0x0001
ldrb ip, [r1], #0x0001
subs r2, r2, #0x00000001 /* Loop test in load delay slot */
orr r3, r3, ip, lsl #8
orr r3, r3, r3, lsl #16
str r3, [r0]
bgt .Loutswloop
mov pc, lr
/* Word aligned outsw */
.Lfastoutsw:
.Lfastoutswloop:
ldr r3, [r1], #0x0004 /* r3 = (H)(L) */
subs r2, r2, #0x00000002 /* Loop test in load delay slot */
eor ip, r3, r3, lsr #16 /* ip = (H)(H^L) */
eor r3, r3, ip, lsl #16 /* r3 = (H^H^L)(L) = (L)(L) */
eor ip, ip, r3, lsr #16 /* ip = (H)(H^L^L) = (H)(H) */
str r3, [r0]
str ip, [r0]
/* mov ip, r3, lsl #16
* orr ip, ip, ip, lsr #16
* str ip, [r0]
*
* mov ip, r3, lsr #16
* orr ip, ip, ip, lsl #16
* str ip, [r0]
*/
bgt .Lfastoutswloop
mov pc, lr
/*
* reads short ints (16 bits) from an I/O address into a block of memory
* with a length garenteed to be a multiple of 16 bytes
* with a word aligned destination address
*
* r0 = address to read from (IO)
* r1 = address to write to (memory)
* r2 = length
*/
ENTRY(insw16)
/* Make sure that we have a positive length */
cmp r2, #0x00000000
movle pc, lr
/* If the destination address is word aligned and the size suitably
aligned, do it fast */
tst r2, #0x00000007
tsteq r1, #0x00000003
bne _C_LABEL(insw)
/* Word aligned insw */
stmfd sp!, {r4,r5,lr}
.Linsw16loop:
ldr r3, [r0, #0x0002] /* take advantage of nonaligned
* word accesses */
ldr lr, [r0]
mov r3, r3, lsr #16 /* Put the two shorts together */
orr r3, r3, lr, lsl #16
ldr r4, [r0, #0x0002] /* take advantage of nonaligned
* word accesses */
ldr lr, [r0]
mov r4, r4, lsr #16 /* Put the two shorts together */
orr r4, r4, lr, lsl #16
ldr r5, [r0, #0x0002] /* take advantage of nonaligned
* word accesses */
ldr lr, [r0]
mov r5, r5, lsr #16 /* Put the two shorts together */
orr r5, r5, lr, lsl #16
ldr ip, [r0, #0x0002] /* take advantage of nonaligned
* word accesses */
ldr lr, [r0]
mov ip, ip, lsr #16 /* Put the two shorts together */
orr ip, ip, lr, lsl #16
stmia r1!, {r3-r5,ip}
subs r2, r2, #0x00000008 /* Next */
bgt .Linsw16loop
ldmfd sp!, {r4,r5,pc} /* Restore regs and go home */
/*
* Writes short ints (16 bits) from a block of memory to an I/O address
*
* r0 = address to write to (IO)
* r1 = address to read from (memory)
* r2 = length
*/
ENTRY(outsw16)
/* Make sure that we have a positive length */
cmp r2, #0x00000000
movle pc, lr
/* If the destination address is word aligned and the size suitably
aligned, do it fast */
tst r2, #0x00000007
tsteq r1, #0x00000003
bne _C_LABEL(outsw)
/* Word aligned outsw */
stmfd sp!, {r4,r5,lr}
.Loutsw16loop:
ldmia r1!, {r4,r5,ip,lr}
eor r3, r4, r4, lsl #16 /* r3 = (A^B)(B) */
eor r4, r4, r3, lsr #16 /* r4 = (A)(B^A^B) = (A)(A) */
eor r3, r3, r4, lsl #16 /* r3 = (A^B^A)(B) = (B)(B) */
str r3, [r0]
str r4, [r0]
/* mov r3, r4, lsl #16
* orr r3, r3, r3, lsr #16
* str r3, [r0]
*
* mov r3, r4, lsr #16
* orr r3, r3, r3, lsl #16
* str r3, [r0]
*/
eor r3, r5, r5, lsl #16 /* r3 = (A^B)(B) */
eor r5, r5, r3, lsr #16 /* r4 = (A)(B^A^B) = (A)(A) */
eor r3, r3, r5, lsl #16 /* r3 = (A^B^A)(B) = (B)(B) */
str r3, [r0]
str r5, [r0]
eor r3, ip, ip, lsl #16 /* r3 = (A^B)(B) */
eor ip, ip, r3, lsr #16 /* r4 = (A)(B^A^B) = (A)(A) */
eor r3, r3, ip, lsl #16 /* r3 = (A^B^A)(B) = (B)(B) */
str r3, [r0]
str ip, [r0]
eor r3, lr, lr, lsl #16 /* r3 = (A^B)(B) */
eor lr, lr, r3, lsr #16 /* r4 = (A)(B^A^B) = (A)(A) */
eor r3, r3, lr, lsl #16 /* r3 = (A^B^A)(B) = (B)(B) */
str r3, [r0]
str lr, [r0]
subs r2, r2, #0x00000008
bgt .Loutsw16loop
ldmfd sp!, {r4,r5,pc} /* and go home */
/*
* reads short ints (16 bits) from an I/O address into a block of memory
* The I/O address is assumed to be mapped multiple times in a block of
* 8 words.
* The destination address should be word aligned.
*
* r0 = address to read from (IO)
* r1 = address to write to (memory)
* r2 = length
*/
ENTRY(inswm8)
/* Make sure that we have a positive length */
cmp r2, #0x00000000
movle pc, lr
/* If the destination address is word aligned and the size suitably
aligned, do it fast */
tst r1, #0x00000003
bne _C_LABEL(insw)
/* Word aligned insw */
stmfd sp!, {r4-r9,lr}
mov lr, #0xff000000
orr lr, lr, #0x00ff0000
.Linswm8_loop8:
cmp r2, #8
bcc .Linswm8_l8
ldmia r0, {r3-r9,ip}
bic r3, r3, lr
orr r3, r3, r4, lsl #16
bic r5, r5, lr
orr r4, r5, r6, lsl #16
bic r7, r7, lr
orr r5, r7, r8, lsl #16
bic r9, r9, lr
orr r6, r9, ip, lsl #16
stmia r1!, {r3-r6}
subs r2, r2, #0x00000008 /* Next */
bne .Linswm8_loop8
beq .Linswm8_l1
.Linswm8_l8:
cmp r2, #4
bcc .Linswm8_l4
ldmia r0, {r3-r6}
bic r3, r3, lr
orr r3, r3, r4, lsl #16
bic r5, r5, lr
orr r4, r5, r6, lsl #16
stmia r1!, {r3-r4}
subs r2, r2, #0x00000004
beq .Linswm8_l1
.Linswm8_l4:
cmp r2, #2
bcc .Linswm8_l2
ldmia r0, {r3-r4}
bic r3, r3, lr
orr r3, r3, r4, lsl #16
str r3, [r1], #0x0004
subs r2, r2, #0x00000002
beq .Linswm8_l1
.Linswm8_l2:
cmp r2, #1
bcc .Linswm8_l1
ldr r3, [r0]
subs r2, r2, #0x00000001 /* Test in load delay slot */
/* XXX, why don't we use result? */
strb r3, [r1], #0x0001
mov r3, r3, lsr #8
strb r3, [r1], #0x0001
.Linswm8_l1:
ldmfd sp!, {r4-r9,pc} /* And go home */
/*
* write short ints (16 bits) to an I/O address from a block of memory
* The I/O address is assumed to be mapped multiple times in a block of
* 8 words.
* The source address should be word aligned.
*
* r0 = address to read to (IO)
* r1 = address to write from (memory)
* r2 = length
*/
ENTRY(outswm8)
/* Make sure that we have a positive length */
cmp r2, #0x00000000
movle pc, lr
/* If the destination address is word aligned and the size suitably
aligned, do it fast */
tst r1, #0x00000003
bne _C_LABEL(outsw)
/* Word aligned outsw */
stmfd sp!, {r4-r8,lr}
.Loutswm8_loop8:
cmp r2, #8
bcc .Loutswm8_l8
ldmia r1!, {r3,r5,r7,ip}
eor r4, r3, r3, lsr #16 /* r4 = (A)(A^B) */
eor r3, r3, r4, lsl #16 /* r3 = (A^A^B)(B) = (B)(B) */
eor r4, r4, r3, lsr #16 /* r4 = (A)(B^A^B) = (A)(A) */
eor r6, r5, r5, lsr #16 /* r6 = (A)(A^B) */
eor r5, r5, r6, lsl #16 /* r5 = (A^A^B)(B) = (B)(B) */
eor r6, r6, r5, lsr #16 /* r6 = (A)(B^A^B) = (A)(A) */
eor r8, r7, r7, lsr #16 /* r8 = (A)(A^B) */
eor r7, r7, r8, lsl #16 /* r7 = (A^A^B)(B) = (B)(B) */
eor r8, r8, r7, lsr #16 /* r8 = (A)(B^A^B) = (A)(A) */
eor lr, ip, ip, lsr #16 /* lr = (A)(A^B) */
eor ip, ip, lr, lsl #16 /* ip = (A^A^B)(B) = (B)(B) */
eor lr, lr, ip, lsr #16 /* lr = (A)(B^A^B) = (A)(A) */
stmia r0, {r3-r8,ip,lr}
subs r2, r2, #0x00000008 /* Next */
bne .Loutswm8_loop8
beq .Loutswm8_l1
.Loutswm8_l8:
cmp r2, #4
bcc .Loutswm8_l4
ldmia r1!, {r3-r4}
eor r6, r3, r3, lsr #16 /* r6 = (A)(A^B) */
eor r5, r3, r6, lsl #16 /* r5 = (A^A^B)(B) = (B)(B) */
eor r6, r6, r5, lsr #16 /* r6 = (A)(B^A^B) = (A)(A) */
eor r8, r4, r4, lsr #16 /* r8 = (A)(A^B) */
eor r7, r4, r8, lsl #16 /* r7 = (A^A^B)(B) = (B)(B) */
eor r8, r8, r7, lsr #16 /* r8 = (A)(B^A^B) = (A)(A) */
stmia r0, {r5-r8}
subs r2, r2, #0x00000004
beq .Loutswm8_l1
.Loutswm8_l4:
cmp r2, #2
bcc .Loutswm8_l2
ldr r3, [r1], #0x0004 /* r3 = (A)(B) */
subs r2, r2, #0x00000002 /* Done test in Load delay slot */
eor r5, r3, r3, lsr #16 /* r5 = (A)(A^B)*/
eor r4, r3, r5, lsl #16 /* r4 = (A^A^B)(B) = (B)(B) */
eor r5, r5, r4, lsr #16 /* r5 = (A)(B^A^B) = (A)(A) */
stmia r0, {r4, r5}
beq .Loutswm8_l1
.Loutswm8_l2:
cmp r2, #1
bcc .Loutswm8_l1
ldrb r3, [r1], #0x0001
ldrb r4, [r1], #0x0001
subs r2, r2, #0x00000001 /* Done test in load delay slot */
/* XXX This test isn't used? */
orr r3, r3, r4, lsl #8
orr r3, r3, r3, lsl #16
str r3, [r0]
.Loutswm8_l1:
ldmfd sp!, {r4-r8,pc} /* And go home */

126
sys/arm/arm/bootconfig.c Normal file
View File

@ -0,0 +1,126 @@
/* $NetBSD: bootconfig.c,v 1.2 2002/03/10 19:56:39 lukem Exp $ */
/*
* Copyright (c) 1994-1998 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe
* for the NetBSD Project.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <machine/bootconfig.h>
/*
* Function to identify and process different types of boot argument
*/
int
get_bootconf_option(opts, opt, type, result)
char *opts;
char *opt;
int type;
void *result;
{
char *ptr;
char *optstart;
int not;
ptr = opts;
while (*ptr) {
/* Find start of option */
while (*ptr == ' ' || *ptr == '\t')
++ptr;
if (*ptr == 0)
break;
not = 0;
/* Is it a negate option */
if ((type & BOOTOPT_TYPE_MASK) == BOOTOPT_TYPE_BOOLEAN && *ptr == '!') {
not = 1;
++ptr;
}
/* Find the end of option */
optstart = ptr;
while (*ptr != 0 && *ptr != ' ' && *ptr != '\t' && *ptr != '=')
++ptr;
if ((*ptr == '=')
|| (*ptr != '=' && ((type & BOOTOPT_TYPE_MASK) == BOOTOPT_TYPE_BOOLEAN))) {
/* compare the option */
if (strncmp(optstart, opt, (ptr - optstart)) == 0) {
/* found */
if (*ptr == '=')
++ptr;
switch(type & BOOTOPT_TYPE_MASK) {
case BOOTOPT_TYPE_BOOLEAN :
if (*(ptr - 1) == '=')
*((int *)result) = ((u_int)strtoul(ptr, NULL, 10) != 0);
else
*((int *)result) = !not;
break;
case BOOTOPT_TYPE_STRING :
*((char **)result) = ptr;
break;
case BOOTOPT_TYPE_INT :
*((int *)result) = (u_int)strtoul(ptr, NULL, 10);
break;
case BOOTOPT_TYPE_BININT :
*((int *)result) = (u_int)strtoul(ptr, NULL, 2);
break;
case BOOTOPT_TYPE_HEXINT :
*((int *)result) = (u_int)strtoul(ptr, NULL, 16);
break;
default:
return(0);
}
return(1);
}
}
/* skip to next option */
while (*ptr != ' ' && *ptr != '\t' && *ptr != 0)
++ptr;
}
return(0);
}

View File

@ -0,0 +1,353 @@
/* $NetBSD: bus_space_asm_generic.S,v 1.3 2003/03/27 19:46:14 mycroft Exp $ */
/*
* Copyright (c) 1997 Causality Limited.
* Copyright (c) 1997 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe
* for the NetBSD Project.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <machine/asm.h>
#include <machine/cpuconf.h>
__FBSDID("$FreeBSD$");
/*
* Generic bus_space functions.
*/
/*
* read single
*/
ENTRY(generic_bs_r_1)
ldrb r0, [r1, r2]
mov pc, lr
#if (ARM_ARCH_4 + ARM_ARCH_5) > 0
ENTRY(generic_armv4_bs_r_2)
ldrh r0, [r1, r2]
mov pc, lr
#endif
ENTRY(generic_bs_r_4)
ldr r0, [r1, r2]
mov pc, lr
/*
* write single
*/
ENTRY(generic_bs_w_1)
strb r3, [r1, r2]
mov pc, lr
#if (ARM_ARCH_4 + ARM_ARCH_5) > 0
ENTRY(generic_armv4_bs_w_2)
strh r3, [r1, r2]
mov pc, lr
#endif
ENTRY(generic_bs_w_4)
str r3, [r1, r2]
mov pc, lr
/*
* read multiple
*/
ENTRY(generic_bs_rm_1)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldrb r3, [r0]
strb r3, [r1], #1
subs r2, r2, #1
bne 1b
mov pc, lr
#if (ARM_ARCH_4 + ARM_ARCH_5) > 0
ENTRY(generic_armv4_bs_rm_2)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldrh r3, [r0]
strh r3, [r1], #2
subs r2, r2, #1
bne 1b
mov pc, lr
#endif
ENTRY(generic_bs_rm_4)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldr r3, [r0]
str r3, [r1], #4
subs r2, r2, #1
bne 1b
mov pc, lr
/*
* write multiple
*/
ENTRY(generic_bs_wm_1)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldrb r3, [r1], #1
strb r3, [r0]
subs r2, r2, #1
bne 1b
mov pc, lr
#if (ARM_ARCH_4 + ARM_ARCH_5) > 0
ENTRY(generic_armv4_bs_wm_2)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldrh r3, [r1], #2
strh r3, [r0]
subs r2, r2, #1
bne 1b
mov pc, lr
#endif
ENTRY(generic_bs_wm_4)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldr r3, [r1], #4
str r3, [r0]
subs r2, r2, #1
bne 1b
mov pc, lr
/*
* read region
*/
ENTRY(generic_bs_rr_1)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldrb r3, [r0], #1
strb r3, [r1], #1
subs r2, r2, #1
bne 1b
mov pc, lr
#if (ARM_ARCH_4 + ARM_ARCH_5) > 0
ENTRY(generic_armv4_bs_rr_2)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldrh r3, [r0], #2
strh r3, [r1], #2
subs r2, r2, #1
bne 1b
mov pc, lr
#endif
ENTRY(generic_bs_rr_4)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldr r3, [r0], #4
str r3, [r1], #4
subs r2, r2, #1
bne 1b
mov pc, lr
/*
* write region.
*/
ENTRY(generic_bs_wr_1)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldrb r3, [r1], #1
strb r3, [r0], #1
subs r2, r2, #1
bne 1b
mov pc, lr
#if (ARM_ARCH_4 + ARM_ARCH_5) > 0
ENTRY(generic_armv4_bs_wr_2)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldrh r3, [r1], #2
strh r3, [r0], #2
subs r2, r2, #1
bne 1b
mov pc, lr
#endif
ENTRY(generic_bs_wr_4)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: ldr r3, [r1], #4
str r3, [r0], #4
subs r2, r2, #1
bne 1b
mov pc, lr
/*
* set region
*/
ENTRY(generic_bs_sr_1)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: strb r1, [r0], #1
subs r2, r2, #1
bne 1b
mov pc, lr
#if (ARM_ARCH_4 + ARM_ARCH_5) > 0
ENTRY(generic_armv4_bs_sr_2)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: strh r1, [r0], #2
subs r2, r2, #1
bne 1b
mov pc, lr
#endif
ENTRY(generic_bs_sr_4)
add r0, r1, r2
mov r1, r3
ldr r2, [sp, #0]
teq r2, #0
moveq pc, lr
1: str r1, [r0], #4
subs r2, r2, #1
bne 1b
mov pc, lr
/*
* copy region
*/
#if (ARM_ARCH_4 + ARM_ARCH_5) > 0
ENTRY(generic_armv4_bs_c_2)
add r0, r1, r2
ldr r2, [sp, #0]
add r1, r2, r3
ldr r2, [sp, #4]
teq r2, #0
moveq pc, lr
cmp r0, r1
blt 2f
1: ldrh r3, [r0], #2
strh r3, [r1], #2
subs r2, r2, #1
bne 1b
mov pc, lr
2: add r0, r0, r2, lsl #1
add r1, r1, r2, lsl #1
sub r0, r0, #2
sub r1, r1, #2
3: ldrh r3, [r0], #-2
strh r3, [r1], #-2
subs r2, r2, #1
bne 3b
mov pc, lr
#endif

View File

@ -0,0 +1,677 @@
/*
* Copyright (c) 2004 Olivier Houchard
* Copyright (c) 2002 Peter Grehan
* Copyright (c) 1997, 1998 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* From i386/busdma_machdep.c,v 1.26 2002/04/19 22:58:09 alfred
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* MacPPC bus dma support routines
*/
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/lock.h>
#include <sys/proc.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/uio.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <machine/atomic.h>
#include <machine/bus.h>
#include <machine/cpufunc.h>
struct bus_dma_tag {
bus_dma_tag_t parent;
bus_size_t alignment;
bus_size_t boundary;
bus_addr_t lowaddr;
bus_addr_t highaddr;
bus_dma_filter_t *filter;
void *filterarg;
bus_size_t maxsize;
u_int nsegments;
bus_size_t maxsegsz;
int flags;
int ref_count;
int map_count;
bus_dma_lock_t *lockfunc;
void *lockfuncarg;
/*
* DMA range for this tag. If the page doesn't fall within
* one of these ranges, an error is returned. The caller
* may then decide what to do with the transfer. If the
* range pointer is NULL, it is ignored.
*/
struct arm32_dma_range *ranges;
int _nranges;
};
struct arm_seglist {
bus_dma_segment_t seg;
SLIST_ENTRY(arm_seglist) next;
};
#define MAX_SEGS 512
struct bus_dmamap {
bus_dma_tag_t dmat;
int flags;
SLIST_HEAD(, arm_seglist) seglist;
};
/*
* Check to see if the specified page is in an allowed DMA range.
*/
static int
bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t segs[],
bus_dmamap_t map, void *buf, bus_size_t buflen, struct thread *td,
int flags, vm_offset_t *lastaddrp, int *segp,
int first);
static __inline struct arm32_dma_range *
_bus_dma_inrange(struct arm32_dma_range *ranges, int nranges,
bus_addr_t curaddr)
{
struct arm32_dma_range *dr;
int i;
for (i = 0, dr = ranges; i < nranges; i++, dr++) {
if (curaddr >= dr->dr_sysbase &&
round_page(curaddr) <= (dr->dr_sysbase + dr->dr_len))
return (dr);
}
return (NULL);
}
/*
* Convenience function for manipulating driver locks from busdma (during
* busdma_swi, for example). Drivers that don't provide their own locks
* should specify &Giant to dmat->lockfuncarg. Drivers that use their own
* non-mutex locking scheme don't have to use this at all.
*/
void
busdma_lock_mutex(void *arg, bus_dma_lock_op_t op)
{
struct mtx *dmtx;
dmtx = (struct mtx *)arg;
switch (op) {
case BUS_DMA_LOCK:
mtx_lock(dmtx);
break;
case BUS_DMA_UNLOCK:
mtx_unlock(dmtx);
break;
default:
panic("Unknown operation 0x%x for busdma_lock_mutex!", op);
}
}
/*
* dflt_lock should never get called. It gets put into the dma tag when
* lockfunc == NULL, which is only valid if the maps that are associated
* with the tag are meant to never be defered.
* XXX Should have a way to identify which driver is responsible here.
*/
static void
dflt_lock(void *arg, bus_dma_lock_op_t op)
{
#ifdef INVARIANTS
panic("driver error: busdma dflt_lock called");
#else
printf("DRIVER_ERROR: busdma dflt_lock called\n");
#endif
}
/*
* Allocate a device specific dma_tag.
*/
int
bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
bus_size_t boundary, bus_addr_t lowaddr,
bus_addr_t highaddr, bus_dma_filter_t *filter,
void *filterarg, bus_size_t maxsize, int nsegments,
bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
void *lockfuncarg, bus_dma_tag_t *dmat)
{
bus_dma_tag_t newtag;
int error = 0;
/* Return a NULL tag on failure */
*dmat = NULL;
newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, M_NOWAIT);
if (newtag == NULL)
return (ENOMEM);
newtag->parent = parent;
newtag->alignment = alignment;
newtag->boundary = boundary;
newtag->lowaddr = trunc_page((vm_offset_t)lowaddr) + (PAGE_SIZE - 1);
newtag->highaddr = trunc_page((vm_offset_t)highaddr) + (PAGE_SIZE - 1);
newtag->filter = filter;
newtag->filterarg = filterarg;
newtag->maxsize = maxsize;
newtag->nsegments = nsegments;
newtag->maxsegsz = maxsegsz;
newtag->flags = flags;
newtag->ref_count = 1; /* Count ourself */
newtag->map_count = 0;
newtag->ranges = bus_dma_get_range();
if (lockfunc != NULL) {
newtag->lockfunc = lockfunc;
newtag->lockfuncarg = lockfuncarg;
} else {
newtag->lockfunc = dflt_lock;
newtag->lockfuncarg = NULL;
}
/*
* Take into account any restrictions imposed by our parent tag
*/
if (parent != NULL) {
newtag->lowaddr = min(parent->lowaddr, newtag->lowaddr);
newtag->highaddr = max(parent->highaddr, newtag->highaddr);
/*
* XXX Not really correct??? Probably need to honor boundary
* all the way up the inheritence chain.
*/
newtag->boundary = max(parent->boundary, newtag->boundary);
if (newtag->filter == NULL) {
/*
* Short circuit looking at our parent directly
* since we have encapsulated all of its information
*/
newtag->filter = parent->filter;
newtag->filterarg = parent->filterarg;
newtag->parent = parent->parent;
}
if (newtag->parent != NULL)
atomic_add_int(&parent->ref_count, 1);
}
*dmat = newtag;
return (error);
}
int
bus_dma_tag_destroy(bus_dma_tag_t dmat)
{
if (dmat != NULL) {
if (dmat->map_count != 0)
return (EBUSY);
while (dmat != NULL) {
bus_dma_tag_t parent;
parent = dmat->parent;
atomic_subtract_int(&dmat->ref_count, 1);
if (dmat->ref_count == 0) {
free(dmat, M_DEVBUF);
/*
* Last reference count, so
* release our reference
* count on our parent.
*/
dmat = parent;
} else
dmat = NULL;
}
}
return (0);
}
static void
arm_dmamap_freesegs(bus_dmamap_t map)
{
struct arm_seglist *seg = SLIST_FIRST(&map->seglist);
while (seg) {
struct arm_seglist *next;
next = SLIST_NEXT(seg, next);
SLIST_REMOVE_HEAD(&map->seglist, next);
free(seg, M_DEVBUF);
seg = next;
}
}
static int
arm_dmamap_addseg(bus_dmamap_t map, vm_offset_t addr, vm_size_t size)
{
struct arm_seglist *seg = malloc(sizeof(*seg), M_DEVBUF, M_NOWAIT);
if (!seg)
return (ENOMEM);
seg->seg.ds_addr = addr;
seg->seg.ds_len = size;
SLIST_INSERT_HEAD(&map->seglist, seg, next);
return (0);
}
/*
* Allocate a handle for mapping from kva/uva/physical
* address space into bus device space.
*/
int
bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
{
bus_dmamap_t newmap;
newmap = malloc(sizeof(*newmap), M_DEVBUF, M_NOWAIT | M_ZERO);
if (newmap == NULL)
return (ENOMEM);
SLIST_INIT(&newmap->seglist);
*mapp = newmap;
dmat->map_count++;
return (0);
}
/*
* Destroy a handle for mapping from kva/uva/physical
* address space into bus device space.
*/
int
bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
{
arm_dmamap_freesegs(map);
free(map, M_DEVBUF);
dmat->map_count--;
return (0);
}
/*
* Allocate a piece of memory that can be efficiently mapped into
* bus device space based on the constraints lited in the dma tag.
* A dmamap to for use with dmamap_load is also allocated.
*/
int
bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
bus_dmamap_t *mapp)
{
bus_dmamap_t newmap;
int mflags;
if (flags & BUS_DMA_NOWAIT)
mflags = M_NOWAIT;
else
mflags = M_WAITOK;
if (flags & BUS_DMA_ZERO)
mflags |= M_ZERO;
newmap = malloc(sizeof(*newmap), M_DEVBUF, M_NOWAIT | M_ZERO);
if (newmap == NULL)
return (ENOMEM);
SLIST_INIT(&newmap->seglist);
*mapp = newmap;
if (dmat->maxsize <= PAGE_SIZE) {
*vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags);
} else {
/*
* XXX Use Contigmalloc until it is merged into this facility
* and handles multi-seg allocations. Nobody is doing
* multi-seg allocations yet though.
*/
*vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags,
0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul,
dmat->boundary);
}
if (*vaddr == NULL) {
free(newmap, M_DEVBUF);
*mapp = NULL;
return (ENOMEM);
}
return (0);
}
/*
* Free a piece of memory and it's allocated dmamap, that was allocated
* via bus_dmamem_alloc. Make the same choice for free/contigfree.
*/
void
bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
{
if (map != NULL)
panic("bus_dmamem_free: Invalid map freed\n");
if (dmat->maxsize <= PAGE_SIZE)
free(vaddr, M_DEVBUF);
else {
contigfree(vaddr, dmat->maxsize, M_DEVBUF);
}
arm_dmamap_freesegs(map);
free(map, M_DEVBUF);
}
/*
* Map the buffer buf into bus space using the dmamap map.
*/
int
bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
bus_size_t buflen, bus_dmamap_callback_t *callback,
void *callback_arg, int flags)
{
vm_offset_t lastaddr = 0;
int error, nsegs = 0;
#ifdef __GNUC__
bus_dma_segment_t dm_segments[dmat->nsegments];
#else
bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
#endif
error = bus_dmamap_load_buffer(dmat,
dm_segments, map, buf, buflen, NULL,
flags, &lastaddr, &nsegs, 1);
(*callback)(callback_arg, dm_segments, nsegs, error);
return (0);
}
/*
* Utility function to load a linear buffer. lastaddrp holds state
* between invocations (for multiple-buffer loads). segp contains
* the starting segment on entrance, and the ending segment on exit.
* first indicates if this is the first invocation of this function.
*/
static int
bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t segs[],
bus_dmamap_t map, void *buf, bus_size_t buflen, struct thread *td,
int flags, vm_offset_t *lastaddrp, int *segp,
int first)
{
bus_size_t sgsize;
bus_addr_t curaddr, lastaddr, baddr, bmask;
vm_offset_t vaddr = (vm_offset_t)buf;
int seg;
int error = 0;
pmap_t pmap;
pd_entry_t *pde;
pt_entry_t pte;
pt_entry_t *ptep;
if (td != NULL)
pmap = vmspace_pmap(td->td_proc->p_vmspace);
else
pmap = NULL;
lastaddr = *lastaddrp;
bmask = ~(dmat->boundary - 1);
for (seg = *segp; buflen > 0 ; ) {
/*
* Get the physical address for this segment.
*
* XXX Don't support checking for coherent mappings
* XXX in user address space.
*/
if (__predict_true(pmap == pmap_kernel())) {
(void) pmap_get_pde_pte(pmap, vaddr, &pde, &ptep);
if (__predict_false(pmap_pde_section(pde))) {
curaddr = (*pde & L1_S_FRAME) |
(vaddr & L1_S_OFFSET);
if (*pde & L1_S_CACHE_MASK) {
map->flags &=
~ARM32_DMAMAP_COHERENT;
}
} else {
pte = *ptep;
KASSERT((pte & L2_TYPE_MASK) != L2_TYPE_INV,
"INV type");
if (__predict_false((pte & L2_TYPE_MASK)
== L2_TYPE_L)) {
curaddr = (pte & L2_L_FRAME) |
(vaddr & L2_L_OFFSET);
if (pte & L2_L_CACHE_MASK) {
map->flags &=
~ARM32_DMAMAP_COHERENT;
}
} else {
curaddr = (pte & L2_S_FRAME) |
(vaddr & L2_S_OFFSET);
if (pte & L2_S_CACHE_MASK) {
map->flags &=
~ARM32_DMAMAP_COHERENT;
}
}
}
} else {
curaddr = pmap_extract(pmap, vaddr);
map->flags &= ~ARM32_DMAMAP_COHERENT;
}
/*
* Compute the segment size, and adjust counts.
*/
sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
if (buflen < sgsize)
sgsize = buflen;
/*
* Make sure we don't cross any boundaries.
*/
if (dmat->boundary > 0) {
baddr = (curaddr + dmat->boundary) & bmask;
if (sgsize > (baddr - curaddr))
sgsize = (baddr - curaddr);
}
/*
* Insert chunk into a segment, coalescing with
* the previous segment if possible.
*/
error = arm_dmamap_addseg(map,
(vm_offset_t)curaddr, sgsize);
if (error)
break;
if (first) {
segs[seg].ds_addr = curaddr;
segs[seg].ds_len = sgsize;
first = 0;
} else {
if (curaddr == lastaddr &&
(segs[seg].ds_len + sgsize) <= dmat->maxsegsz &&
(dmat->boundary == 0 ||
(segs[seg].ds_addr & bmask) == (curaddr & bmask)))
segs[seg].ds_len += sgsize;
else {
if (++seg >= dmat->nsegments)
break;
segs[seg].ds_addr = curaddr;
segs[seg].ds_len = sgsize;
}
}
lastaddr = curaddr + sgsize;
vaddr += sgsize;
buflen -= sgsize;
}
*segp = seg;
*lastaddrp = lastaddr;
/*
* Did we fit?
*/
if (buflen != 0)
error = EFBIG; /* XXX better return value here? */
return (error);
}
/*
* Like bus_dmamap_load(), but for mbufs.
*/
int
bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0,
bus_dmamap_callback2_t *callback, void *callback_arg,
int flags)
{
#ifdef __GNUC__
bus_dma_segment_t dm_segments[dmat->nsegments];
#else
bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
#endif
int nsegs = 0, error = 0;
M_ASSERTPKTHDR(m0);
if (m0->m_pkthdr.len <= dmat->maxsize) {
int first = 1;
vm_offset_t lastaddr = 0;
struct mbuf *m;
for (m = m0; m != NULL && error == 0; m = m->m_next) {
if (m->m_len > 0) {
error = bus_dmamap_load_buffer(dmat,
dm_segments, map, m->m_data, m->m_len, NULL,
flags, &lastaddr, &nsegs, first);
first = 0;
}
}
} else {
error = EINVAL;
}
if (error) {
/*
* force "no valid mappings" on error in callback.
*/
(*callback)(callback_arg, dm_segments, 0, 0, error);
} else {
(*callback)(callback_arg, dm_segments, nsegs+1,
m0->m_pkthdr.len, error);
}
return (error);
}
/*
* Like bus_dmamap_load(), but for uios.
*/
int
bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio,
bus_dmamap_callback2_t *callback, void *callback_arg,
int flags)
{
vm_offset_t lastaddr;
#ifdef __GNUC__
bus_dma_segment_t dm_segments[dmat->nsegments];
#else
bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
#endif
int nsegs, i, error, first;
bus_size_t resid;
struct iovec *iov;
struct thread *td = NULL;
resid = uio->uio_resid;
iov = uio->uio_iov;
if (uio->uio_segflg == UIO_USERSPACE) {
td = uio->uio_td;
KASSERT(td != NULL,
("bus_dmamap_load_uio: USERSPACE but no proc"));
}
first = 1;
nsegs = error = 0;
for (i = 0; i < uio->uio_iovcnt && resid != 0 && !error; i++) {
/*
* Now at the first iovec to load. Load each iovec
* until we have exhausted the residual count.
*/
bus_size_t minlen =
resid < iov[i].iov_len ? resid : iov[i].iov_len;
caddr_t addr = (caddr_t) iov[i].iov_base;
if (minlen > 0) {
error = bus_dmamap_load_buffer(dmat, dm_segments, map,
addr, minlen, td, flags, &lastaddr, &nsegs, first);
first = 0;
resid -= minlen;
}
}
if (error) {
/*
* force "no valid mappings" on error in callback.
*/
(*callback)(callback_arg, dm_segments, 0, 0, error);
} else {
(*callback)(callback_arg, dm_segments, nsegs+1,
uio->uio_resid, error);
}
return (error);
}
/*
* Release the mapping held by map. A no-op on PowerPC.
*/
void
bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
{
arm_dmamap_freesegs(map);
return;
}
void
bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
{
struct arm_seglist *seg = SLIST_FIRST(&map->seglist);
if (op != BUS_DMASYNC_PREREAD && op != BUS_DMASYNC_PREWRITE)
return;
/* Skip cache frobbing if mapping was COHERENT. */
if (map->flags & ARM32_DMAMAP_COHERENT) {
/* Drain the write buffer. */
cpu_drain_writebuf();
return;
}
while (seg) {
cpu_dcache_wbinv_range(seg->seg.ds_addr, seg->seg.ds_len);
seg = SLIST_NEXT(seg, next);
}
}

227
sys/arm/arm/copystr.S Normal file
View File

@ -0,0 +1,227 @@
/* $NetBSD: copystr.S,v 1.8 2002/10/13 14:54:48 bjh21 Exp $ */
/*
* Copyright (c) 1995 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* copystr.S
*
* optimised and fault protected copystr functions
*
* Created : 16/05/95
*/
#include "assym.s"
#include <machine/asm.h>
#include <machine/armreg.h>
#include <machine/asmacros.h>
__FBSDID("$FreeBSD$");
#include <sys/errno.h>
.text
.align 0
#ifdef MULTIPROCESSOR
.Lcpu_info:
.word _C_LABEL(cpu_info)
#else
.Lpcb:
.word _C_LABEL(__pcpu) + PC_CURPCB
#endif
/*
* r0 - from
* r1 - to
* r2 - maxlens
* r3 - lencopied
*
* Copy string from r0 to r1
*/
ENTRY(copystr)
stmfd sp!, {r4-r5} /* stack is 8 byte aligned */
teq r2, #0x00000000
mov r5, #0x00000000
moveq r0, #ENAMETOOLONG
beq 2f
1: ldrb r4, [r0], #0x0001
add r5, r5, #0x00000001
teq r4, #0x00000000
strb r4, [r1], #0x0001
teqne r5, r2
bne 1b
teq r4, #0x00000000
moveq r0, #0x00000000
movne r0, #ENAMETOOLONG
2: teq r3, #0x00000000
strne r5, [r3]
ldmfd sp!, {r4-r5} /* stack is 8 byte aligned */
mov pc, lr
#define SAVE_REGS stmfd sp!, {r4-r6}
#define RESTORE_REGS ldmfd sp!, {r4-r6}
/*
* r0 - user space address
* r1 - kernel space address
* r2 - maxlens
* r3 - lencopied
*
* Copy string from user space to kernel space
*/
ENTRY(copyinstr)
SAVE_REGS
teq r2, #0x00000000
mov r6, #0x00000000
moveq r0, #ENAMETOOLONG
beq 2f
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0-r3, r14}
bl _C_LABEL(cpu_number)
ldr r4, .Lcpu_info
ldr r4, [r4, r0, lsl #2]
ldr r4, [r4, #CI_CURPCB]
ldmfd sp!, {r0-r3, r14}
#else
ldr r4, .Lpcb
ldr r4, [r4]
#endif
#ifdef DIAGNOSTIC
teq r4, #0x00000000
beq .Lcopystrpcbfault
#endif
adr r5, .Lcopystrfault
str r5, [r4, #PCB_ONFAULT]
1: ldrbt r5, [r0], #0x0001
add r6, r6, #0x00000001
teq r5, #0x00000000
strb r5, [r1], #0x0001
teqne r6, r2
bne 1b
mov r0, #0x00000000
str r0, [r4, #PCB_ONFAULT]
teq r5, #0x00000000
moveq r0, #0x00000000
movne r0, #ENAMETOOLONG
2: teq r3, #0x00000000
strne r6, [r3]
RESTORE_REGS
mov pc, lr
/*
* r0 - kernel space address
* r1 - user space address
* r2 - maxlens
* r3 - lencopied
*
* Copy string from kernel space to user space
*/
ENTRY(copyoutstr)
SAVE_REGS
teq r2, #0x00000000
mov r6, #0x00000000
moveq r0, #ENAMETOOLONG
beq 2f
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0-r3, r14}
bl _C_LABEL(cpu_number)
ldr r4, .Lcpu_info
ldr r4, [r4, r0, lsl #2]
ldr r4, [r4, #CI_CURPCB]
ldmfd sp!, {r0-r3, r14}
#else
ldr r4, .Lpcb
ldr r4, [r4]
#endif
#ifdef DIAGNOSTIC
teq r4, #0x00000000
beq .Lcopystrpcbfault
#endif
adr r5, .Lcopystrfault
str r5, [r4, #PCB_ONFAULT]
1: ldrb r5, [r0], #0x0001
add r6, r6, #0x00000001
teq r5, #0x00000000
strbt r5, [r1], #0x0001
teqne r6, r2
bne 1b
mov r0, #0x00000000
str r0, [r4, #PCB_ONFAULT]
teq r5, #0x00000000
moveq r0, #0x00000000
movne r0, #ENAMETOOLONG
2: teq r3, #0x00000000
strne r6, [r3]
RESTORE_REGS
mov pc, lr
/* A fault occurred during the copy */
.Lcopystrfault:
mov r1, #0x00000000
str r1, [r4, #PCB_ONFAULT]
RESTORE_REGS
mov pc, lr
#ifdef DIAGNOSTIC
.Lcopystrpcbfault:
mov r2, r1
mov r1, r0
adr r0, Lcopystrpcbfaulttext
bic sp, sp, #7 /* align stack to 8 bytes */
b _C_LABEL(panic)
Lcopystrpcbfaulttext:
.asciz "No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n"
.align 0
#endif

2177
sys/arm/arm/cpufunc.c Normal file

File diff suppressed because it is too large Load Diff

157
sys/arm/arm/cpufunc_asm.S Normal file
View File

@ -0,0 +1,157 @@
/* $NetBSD: cpufunc_asm.S,v 1.12 2003/09/06 09:14:52 rearnsha Exp $ */
/*
* Copyright (c) 1997,1998 Mark Brinicombe.
* Copyright (c) 1997 Causality Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Causality Limited.
* 4. The name of Causality Limited may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* cpufunc.S
*
* Assembly functions for CPU / MMU / TLB specific operations
*
* Created : 30/01/97
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.text
.align 0
ENTRY(cpufunc_nullop)
mov pc, lr
/*
* Generic functions to read the internal coprocessor registers
*
* Currently these registers are :
* c0 - CPU ID
* c5 - Fault status
* c6 - Fault address
*
*/
ENTRY(cpufunc_id)
mrc p15, 0, r0, c0, c0, 0
mov pc, lr
ENTRY(cpu_get_control)
mrc p15, 0, r0, c1, c0, 0
mov pc, lr
ENTRY(cpu_read_cache_config)
mrc p15, 0, r0, c0, c0, 1
mov pc, lr
ENTRY(cpufunc_faultstatus)
mrc p15, 0, r0, c5, c0, 0
mov pc, lr
ENTRY(cpufunc_faultaddress)
mrc p15, 0, r0, c6, c0, 0
mov pc, lr
/*
* Generic functions to write the internal coprocessor registers
*
*
* Currently these registers are
* c1 - CPU Control
* c3 - Domain Access Control
*
* All other registers are CPU architecture specific
*/
#if 0 /* See below. */
ENTRY(cpufunc_control)
mcr p15, 0, r0, c1, c0, 0
mov pc, lr
#endif
ENTRY(cpufunc_domains)
mcr p15, 0, r0, c3, c0, 0
mov pc, lr
/*
* Generic functions to read/modify/write the internal coprocessor registers
*
*
* Currently these registers are
* c1 - CPU Control
*
* All other registers are CPU architecture specific
*/
ENTRY(cpufunc_control)
mrc p15, 0, r3, c1, c0, 0 /* Read the control register */
bic r2, r3, r0 /* Clear bits */
eor r2, r2, r1 /* XOR bits */
teq r2, r3 /* Only write if there is a change */
mcrne p15, 0, r2, c1, c0, 0 /* Write new control register */
#if 0
mov r0, r3 /* Return old value */
#endif
mov pc, lr
.Lglou:
.asciz "plop %p\n"
.align 0
/*
* other potentially useful software functions are:
* clean D cache entry and flush I cache entry
* for the moment use cache_purgeID_E
*/
/* Random odd functions */
/*
* Function to get the offset of a stored program counter from the
* instruction doing the store. This offset is defined to be the same
* for all STRs and STMs on a given implementation. Code based on
* section 2.4.3 of the ARM ARM (2nd Ed.), with modifications to work
* in 26-bit modes as well.
*/
ENTRY(get_pc_str_offset)
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #4
mov r1, pc /* R1 = addr of following STR */
mov r0, r0
str pc, [sp] /* [SP] = . + offset */
ldr r0, [sp]
sub r0, r0, r1
ldmdb fp, {fp, sp, pc}

View File

@ -0,0 +1,269 @@
/* $NetBSD: cpufunc_asm_arm10.S,v 1.1 2003/09/06 09:12:29 rearnsha Exp $ */
/*
* Copyright (c) 2002 ARM Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the company may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ARM10 assembly functions for CPU / MMU / TLB specific operations
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* Functions to set the MMU Translation Table Base register
*
* We need to clean and flush the cache as it uses virtual
* addresses that are about to change.
*/
ENTRY(arm10_setttb)
stmfd sp!, {r0, lr}
bl _C_LABEL(arm10_idcache_wbinv_all)
ldmfd sp!, {r0, lr}
mcr p15, 0, r0, c2, c0, 0 /* load new TTB */
mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLBs */
bx lr
/*
* TLB functions
*/
ENTRY(arm10_tlb_flushID_SE)
mcr p15, 0, r0, c8, c6, 1 /* flush D tlb single entry */
mcr p15, 0, r0, c8, c5, 1 /* flush I tlb single entry */
bx lr
ENTRY(arm10_tlb_flushI_SE)
mcr p15, 0, r0, c8, c5, 1 /* flush I tlb single entry */
bx lr
/*
* Cache operations. For the entire cache we use the set/index
* operations.
*/
s_max .req r0
i_max .req r1
s_inc .req r2
i_inc .req r3
ENTRY_NP(arm10_icache_sync_range)
ldr ip, .Larm10_line_size
cmp r1, #0x4000
bcs .Larm10_icache_sync_all
ldr ip, [ip]
sub r3, ip, #1
and r2, r0, r3
add r1, r1, r2
bic r0, r0, r3
.Larm10_sync_next:
mcr p15, 0, r0, c7, c5, 1 /* Invalidate I cache SE with VA */
mcr p15, 0, r0, c7, c10, 1 /* Clean D cache SE with VA */
add r0, r0, ip
subs r1, r1, ip
bpl .Larm10_sync_next
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
bx lr
ENTRY_NP(arm10_icache_sync_all)
.Larm10_icache_sync_all:
/*
* We assume that the code here can never be out of sync with the
* dcache, so that we can safely flush the Icache and fall through
* into the Dcache cleaning code.
*/
mcr p15, 0, r0, c7, c5, 0 /* Flush I cache */
/* Fall through to clean Dcache. */
.Larm10_dcache_wb:
ldr ip, .Larm10_cache_data
ldmia ip, {s_max, i_max, s_inc, i_inc}
.Lnext_set:
orr ip, s_max, i_max
.Lnext_index:
mcr p15, 0, ip, c7, c10, 2 /* Clean D cache SE with Set/Index */
sub ip, ip, i_inc
tst ip, i_max /* Index 0 is last one */
bne .Lnext_index /* Next index */
mcr p15, 0, ip, c7, c10, 2 /* Clean D cache SE with Set/Index */
subs s_max, s_max, s_inc
bpl .Lnext_set /* Next set */
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
bx lr
.Larm10_line_size:
.word _C_LABEL(arm_pdcache_line_size)
ENTRY(arm10_dcache_wb_range)
ldr ip, .Larm10_line_size
cmp r1, #0x4000
bcs .Larm10_dcache_wb
ldr ip, [ip]
sub r3, ip, #1
and r2, r0, r3
add r1, r1, r2
bic r0, r0, r3
.Larm10_wb_next:
mcr p15, 0, r0, c7, c10, 1 /* Clean D cache SE with VA */
add r0, r0, ip
subs r1, r1, ip
bpl .Larm10_wb_next
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
bx lr
ENTRY(arm10_dcache_wbinv_range)
ldr ip, .Larm10_line_size
cmp r1, #0x4000
bcs .Larm10_dcache_wbinv_all
ldr ip, [ip]
sub r3, ip, #1
and r2, r0, r3
add r1, r1, r2
bic r0, r0, r3
.Larm10_wbinv_next:
mcr p15, 0, r0, c7, c14, 1 /* Purge D cache SE with VA */
add r0, r0, ip
subs r1, r1, ip
bpl .Larm10_wbinv_next
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
bx lr
/*
* Note, we must not invalidate everything. If the range is too big we
* must use wb-inv of the entire cache.
*/
ENTRY(arm10_dcache_inv_range)
ldr ip, .Larm10_line_size
cmp r1, #0x4000
bcs .Larm10_dcache_wbinv_all
ldr ip, [ip]
sub r3, ip, #1
and r2, r0, r3
add r1, r1, r2
bic r0, r0, r3
.Larm10_inv_next:
mcr p15, 0, r0, c7, c6, 1 /* Invalidate D cache SE with VA */
add r0, r0, ip
subs r1, r1, ip
bpl .Larm10_inv_next
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
bx lr
ENTRY(arm10_idcache_wbinv_range)
ldr ip, .Larm10_line_size
cmp r1, #0x4000
bcs .Larm10_idcache_wbinv_all
ldr ip, [ip]
sub r3, ip, #1
and r2, r0, r3
add r1, r1, r2
bic r0, r0, r3
.Larm10_id_wbinv_next:
mcr p15, 0, r0, c7, c5, 1 /* Invalidate I cache SE with VA */
mcr p15, 0, r0, c7, c14, 1 /* Purge D cache SE with VA */
add r0, r0, ip
subs r1, r1, ip
bpl .Larm10_id_wbinv_next
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
bx lr
ENTRY_NP(arm10_idcache_wbinv_all)
.Larm10_idcache_wbinv_all:
/*
* We assume that the code here can never be out of sync with the
* dcache, so that we can safely flush the Icache and fall through
* into the Dcache purging code.
*/
mcr p15, 0, r0, c7, c5, 0 /* Flush I cache */
/* Fall through to purge Dcache. */
ENTRY(arm10_dcache_wbinv_all)
.Larm10_dcache_wbinv_all:
ldr ip, .Larm10_cache_data
ldmia ip, {s_max, i_max, s_inc, i_inc}
.Lnext_set_inv:
orr ip, s_max, i_max
.Lnext_index_inv:
mcr p15, 0, ip, c7, c14, 2 /* Purge D cache SE with Set/Index */
sub ip, ip, i_inc
tst ip, i_max /* Index 0 is last one */
bne .Lnext_index_inv /* Next index */
mcr p15, 0, ip, c7, c14, 2 /* Purge D cache SE with Set/Index */
subs s_max, s_max, s_inc
bpl .Lnext_set_inv /* Next set */
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
bx lr
.Larm10_cache_data:
.word _C_LABEL(arm10_dcache_sets_max)
/*
* Context switch.
*
* These is the CPU-specific parts of the context switcher cpu_switch()
* These functions actually perform the TTB reload.
*
* NOTE: Special calling convention
* r1, r4-r13 must be preserved
*/
ENTRY(arm10_context_switch)
/*
* We can assume that the caches will only contain kernel addresses
* at this point. So no need to flush them again.
*/
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
mcr p15, 0, r0, c2, c0, 0 /* set the new TTB */
mcr p15, 0, r0, c8, c7, 0 /* and flush the I+D tlbs */
/* Paranoia -- make sure the pipeline is empty. */
nop
nop
nop
bx lr
.bss
/* XXX The following macros should probably be moved to asm.h */
#define _DATA_OBJECT(x) .globl x; .type x,_ASM_TYPE_OBJECT; x:
#define C_OBJECT(x) _DATA_OBJECT(_C_LABEL(x))
/*
* Parameters for the cache cleaning code. Note that the order of these
* four variables is assumed in the code above. Hence the reason for
* declaring them in the assembler file.
*/
.align 0
C_OBJECT(arm10_dcache_sets_max)
.space 4
C_OBJECT(arm10_dcache_index_max)
.space 4
C_OBJECT(arm10_dcache_sets_inc)
.space 4
C_OBJECT(arm10_dcache_index_inc)
.space 4

View File

@ -0,0 +1,61 @@
/* $NetBSD: cpufunc_asm_arm3.S,v 1.1 2001/11/10 23:14:09 thorpej Exp $ */
/*
* Copyright (c) 1997,1998 Mark Brinicombe.
* Copyright (c) 1997 Causality Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Causality Limited.
* 4. The name of Causality Limited may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ARM3 assembly functions for CPU / MMU / TLB specific operations
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* The ARM3 has its own control register in a different place.
*/
ENTRY(arm3_control)
mrc p15, 0, r3, c2, c0, 0 /* Read the control register */
bic r2, r3, r0 /* Clear bits */
eor r2, r2, r1 /* XOR bits */
teq r2, r3 /* Only write if there is a change */
mcrne p15, 0, r2, c2, c0, 0 /* Write new control register */
mov r0, r3 /* Return old value */
mov pc, lr
/*
* Cache functions.
*/
ENTRY(arm3_cache_flush)
mcr p15, 0, r0, c1, c0, 0
mov pc, lr

View File

@ -0,0 +1,111 @@
/* $NetBSD: cpufunc_asm_arm67.S,v 1.1 2001/11/10 23:14:09 thorpej Exp $ */
/*
* Copyright (c) 1997,1998 Mark Brinicombe.
* Copyright (c) 1997 Causality Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Causality Limited.
* 4. The name of Causality Limited may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ARM6/ARM7 assembly functions for CPU / MMU / TLB specific operations
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* Functions to set the MMU Translation Table Base register
*
* We need to clean and flush the cache as it uses virtual
* addresses that are about to change.
*/
ENTRY(arm67_setttb)
mcr p15, 0, r0, c7, c0, 0
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c5, c0, 0
/* For good measure we will flush the IDC as well */
mcr p15, 0, r0, c7, c0, 0
/* Make sure that pipeline is emptied */
mov r0, r0
mov r0, r0
mov pc, lr
/*
* TLB functions
*/
ENTRY(arm67_tlb_flush)
mcr p15, 0, r0, c5, c0, 0
mov pc, lr
ENTRY(arm67_tlb_purge)
mcr p15, 0, r0, c6, c0, 0
mov pc, lr
/*
* Cache functions
*/
ENTRY(arm67_cache_flush)
mcr p15, 0, r0, c7, c0, 0
mov pc, lr
/*
* Context switch.
*
* These is the CPU-specific parts of the context switcher cpu_switch()
* These functions actually perform the TTB reload.
*
* NOTE: Special calling convention
* r1, r4-r13 must be preserved
*/
ENTRY(arm67_context_switch)
/* For good measure we will flush the IDC as well */
mcr p15, 0, r0, c7, c0, 0 /* flush cache */
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c5, c0, 0
#if 0
/* For good measure we will flush the IDC as well */
mcr p15, 0, r0, c7, c0, 0 /* flush cache */
#endif
/* Make sure that pipeline is emptied */
mov r0, r0
mov r0, r0
mov pc, lr

View File

@ -0,0 +1,100 @@
/* $NetBSD: cpufunc_asm_arm7tdmi.S,v 1.1 2001/11/10 23:14:09 thorpej Exp $ */
/*
* Copyright (c) 2001 John Fremlin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Causality Limited.
* 4. The name of Causality Limited may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ARM7TDMI assembly functions for CPU / MMU / TLB specific operations
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* Functions to set the MMU Translation Table Base register
*
* We need to clean and flush the cache as it uses virtual
* addresses that are about to change.
*/
ENTRY(arm7tdmi_setttb)
mov r1, r0 /* store the TTB in a safe place */
mov r2, lr /* ditto with lr */
bl _C_LABEL(arm7tdmi_cache_flushID)
/* Write the TTB */
mcr p15, 0, r1, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
bl _C_LABEL(arm7tdmi_tlb_flushID)
/* For good measure we will flush the IDC as well */
bl _C_LABEL(arm7tdmi_cache_flushID)
mov pc, r2
/*
* TLB functions
*/
ENTRY(arm7tdmi_tlb_flushID)
mov r0, #0
mcr p15, 0, r0, c8, c7, 0
mov pc, lr
ENTRY(arm7tdmi_tlb_flushID_SE)
mcr p15, 0, r0, c8, c7, 1
mov pc, lr
/*
* Cache functions
*/
ENTRY(arm7tdmi_cache_flushID)
mov r0, #0
mcr p15, 0, r0, c7, c7, 0
/* Make sure that the pipeline is emptied */
mov r0, r0
mov r0, r0
mov pc, lr
/*
* Context switch.
*
* These is the CPU-specific parts of the context switcher cpu_switch()
* These functions actually perform the TTB reload.
*
* NOTE: Special calling convention
* r1, r4-r13 must be preserved
*/
ENTRY(arm7tdmi_context_switch)
b _C_LABEL(arm7tdmi_setttb)

View File

@ -0,0 +1,284 @@
/* $NetBSD: cpufunc_asm_arm8.S,v 1.2 2001/11/11 00:47:49 thorpej Exp $ */
/*
* Copyright (c) 1997 ARM Limited
* Copyright (c) 1997 Causality Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Causality Limited.
* 4. The name of Causality Limited may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ARM8 assembly functions for CPU / MMU / TLB specific operations
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
ENTRY(arm8_clock_config)
mrc p15, 0, r3, c15, c0, 0 /* Read the clock register */
bic r2, r3, #0x11 /* turn off dynamic clocking
and clear L bit */
mcr p15, 0, r2, c15, c0, 0 /* Write clock register */
bic r2, r3, r0 /* Clear bits */
eor r2, r2, r1 /* XOR bits */
bic r2, r2, #0x10 /* clear the L bit */
bic r1, r2, #0x01 /* still keep dynamic clocking off */
mcr p15, 0, r1, c15, c0, 0 /* Write clock register */
mov r0, r0 /* NOP */
mov r0, r0 /* NOP */
mov r0, r0 /* NOP */
mov r0, r0 /* NOP */
mcr p15, 0, r2, c15, c0, 0 /* Write clock register */
mov r0, r3 /* Return old value */
mov pc, lr
/*
* Functions to set the MMU Translation Table Base register
*
* We need to clean and flush the cache as it uses virtual
* addresses that are about to change.
*/
ENTRY(arm8_setttb)
mrs r3, cpsr_all
orr r1, r3, #(I32_bit | F32_bit)
msr cpsr_all, r1
stmfd sp!, {r0-r3, lr}
bl _C_LABEL(arm8_cache_cleanID)
ldmfd sp!, {r0-r3, lr}
mcr p15, 0, r0, c7, c7, 0 /* flush I+D cache */
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c8, c7, 0
/* For good measure we will flush the IDC as well */
mcr p15, 0, r0, c7, c7, 0
/* Make sure that pipeline is emptied */
mov r0, r0
mov r0, r0
msr cpsr_all, r3
mov pc, lr
/*
* TLB functions
*/
ENTRY(arm8_tlb_flushID)
mcr p15, 0, r0, c8, c7, 0 /* flush I+D tlb */
mov pc, lr
ENTRY(arm8_tlb_flushID_SE)
mcr p15, 0, r0, c8, c7, 1 /* flush I+D tlb single entry */
mov pc, lr
/*
* Cache functions
*/
ENTRY(arm8_cache_flushID)
mcr p15, 0, r0, c7, c7, 0 /* flush I+D cache */
mov pc, lr
ENTRY(arm8_cache_flushID_E)
mcr p15, 0, r0, c7, c7, 1 /* flush I+D single entry */
mov pc, lr
ENTRY(arm8_cache_cleanID)
mov r0, #0x00000000
1: mov r2, r0
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
adds r0, r0, #0x04000000
bne 1b
mov pc, lr
ENTRY(arm8_cache_cleanID_E)
mcr p15, 0, r0, c7, c11, 1 /* clean I+D single entry */
mov pc, lr
ENTRY(arm8_cache_purgeID)
/*
* ARM810 bug 3
*
* Clean and invalidate entry will not invalidate the entry
* if the line was already clean. (mcr p15, 0, rd, c7, 15, 1)
*
* Instead of using the clean and invalidate entry operation
* use a separate clean and invalidate entry operations.
* i.e.
* mcr p15, 0, rd, c7, c11, 1
* mcr p15, 0, rd, c7, c7, 1
*/
mov r0, #0x00000000
mrs r3, cpsr_all
orr r2, r3, #(I32_bit | F32_bit)
msr cpsr_all, r2
1: mov r2, r0
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
add r2, r2, #0x10
mcr p15, 0, r2, c7, c11, 1
mcr p15, 0, r2, c7, c7, 1
adds r0, r0, #0x04000000
bne 1b
msr cpsr_all, r3
mov pc, lr
ENTRY(arm8_cache_purgeID_E)
/*
* ARM810 bug 3
*
* Clean and invalidate entry will not invalidate the entry
* if the line was already clean. (mcr p15, 0, rd, c7, 15, 1)
*
* Instead of using the clean and invalidate entry operation
* use a separate clean and invalidate entry operations.
* i.e.
* mcr p15, 0, rd, c7, c11, 1
* mcr p15, 0, rd, c7, c7, 1
*/
mrs r3, cpsr_all
orr r2, r3, #(I32_bit | F32_bit)
msr cpsr_all, r2
mcr p15, 0, r0, c7, c11, 1 /* clean I+D single entry */
mcr p15, 0, r0, c7, c7, 1 /* flush I+D single entry */
msr cpsr_all, r3
mov pc, lr
/*
* Context switch.
*
* These is the CPU-specific parts of the context switcher cpu_switch()
* These functions actually perform the TTB reload.
*
* NOTE: Special calling convention
* r1, r4-r13 must be preserved
*/
ENTRY(arm8_context_switch)
/* For good measure we will flush the IDC as well */
mcr p15, 0, r0, c7, c7, 0 /* flush I+D cache */
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */
#if 0
/* For good measure we will flush the IDC as well */
mcr p15, 0, r0, c7, c7, 0 /* flush I+D cache */
#endif
/* Make sure that pipeline is emptied */
mov r0, r0
mov r0, r0
mov pc, lr

View File

@ -0,0 +1,137 @@
/* $NetBSD: cpufunc_asm_arm9.S,v 1.2 2002/01/29 15:27:29 rearnsha Exp $ */
/*
* Copyright (c) 2001 ARM Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the company may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ARM9 assembly functions for CPU / MMU / TLB specific operations
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* Functions to set the MMU Translation Table Base register
*
* We need to clean and flush the cache as it uses virtual
* addresses that are about to change.
*/
ENTRY(arm9_setttb)
/*
* Since we use the caches in write-through mode, we only have to
* drain the write buffers and flush the caches.
*/
mcr p15, 0, r0, c7, c7, 0 /* flush I+D caches */
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mcr p15, 0, r0, c2, c0, 0 /* load new TTB */
mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLBs */
mov pc, lr
/*
* TLB functions
*/
ENTRY(arm9_tlb_flushID_SE)
mcr p15, 0, r0, c8, c6, 1 /* flush D tlb single entry */
mcr p15, 0, r0, c8, c5, 1 /* flush I tlb single entry */
mov pc, lr
/*
* Cache functions
*/
ENTRY(arm9_cache_flushID)
mcr p15, 0, r0, c7, c7, 0 /* flush I+D cache */
mov pc, lr
ENTRY(arm9_cache_flushID_SE)
mcr p15, 0, r0, c7, c5, 1 /* flush one entry from I cache */
mcr p15, 0, r0, c7, c6, 1 /* flush one entry from D cache */
mov pc, lr
ENTRY(arm9_cache_flushI)
mcr p15, 0, r0, c7, c5, 0 /* flush I cache */
mov pc, lr
ENTRY(arm9_cache_flushI_SE)
mcr p15, 0, r0, c7, c5, 1 /* flush one entry from I cache */
mov pc, lr
ENTRY(arm9_cache_flushD)
mcr p15, 0, r0, c7, c6, 0 /* flush D cache */
mov pc, lr
ENTRY(arm9_cache_flushD_SE)
mcr p15, 0, r0, c7, c6, 1 /* flush one entry from D cache */
mov pc, lr
ENTRY(arm9_cache_cleanID)
mcr p15, 0, r0, c7, c10, 4
mov pc, lr
/*
* Soft functions
*/
ENTRY(arm9_cache_syncI)
mcr p15, 0, r0, c7, c7, 0 /* flush I+D caches */
mov pc, lr
ENTRY_NP(arm9_cache_flushID_rng)
b _C_LABEL(arm9_cache_flushID)
ENTRY_NP(arm9_cache_flushD_rng)
/* Same as above, but D cache only */
b _C_LABEL(arm9_cache_flushD)
ENTRY_NP(arm9_cache_syncI_rng)
/* Similarly, for I cache sync */
b _C_LABEL(arm9_cache_syncI)
/*
* Context switch.
*
* These is the CPU-specific parts of the context switcher cpu_switch()
* These functions actually perform the TTB reload.
*
* NOTE: Special calling convention
* r1, r4-r13 must be preserved
*/
ENTRY(arm9_context_switch)
/*
* We can assume that the caches will only contain kernel addresses
* at this point. So no need to flush them again.
*/
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
mcr p15, 0, r0, c2, c0, 0 /* set the new TTB */
mcr p15, 0, r0, c8, c7, 0 /* and flush the I+D tlbs */
/* Paranoia -- make sure the pipeline is empty. */
nop
nop
nop
mov pc, lr

View File

@ -0,0 +1,67 @@
/* $NetBSD: cpufunc_asm_armv4.S,v 1.1 2001/11/10 23:14:09 thorpej Exp $ */
/*
* Copyright (c) 2001 ARM Limited
* Copyright (c) 1997,1998 Mark Brinicombe.
* Copyright (c) 1997 Causality Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Causality Limited.
* 4. The name of Causality Limited may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ARM9 assembly functions for CPU / MMU / TLB specific operations
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* TLB functions
*/
ENTRY(armv4_tlb_flushID)
mcr p15, 0, r0, c8, c7, 0 /* flush I+D tlb */
mov pc, lr
ENTRY(armv4_tlb_flushI)
mcr p15, 0, r0, c8, c5, 0 /* flush I tlb */
mov pc, lr
ENTRY(armv4_tlb_flushD)
mcr p15, 0, r0, c8, c6, 0 /* flush D tlb */
mov pc, lr
ENTRY(armv4_tlb_flushD_SE)
mcr p15, 0, r0, c8, c6, 1 /* flush D tlb single entry */
mov pc, lr
/*
* Other functions
*/
ENTRY(armv4_drain_writebuf)
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mov pc, lr

View File

@ -0,0 +1,90 @@
/* $NetBSD: cpufunc_asm_ixp12x0.S,v 1.2 2002/08/17 16:36:31 thorpej Exp $ */
/*
* Copyright (c) 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* This function is the same as sa110_context_switch for now, the plan
* is to make use of the process id register to avoid cache flushes.
*/
ENTRY(ixp12x0_context_switch)
/*
* CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
* Thus the data cache will contain only kernel data and the
* instruction cache will contain only kernel code, and all
* kernel mappings are shared by all processes.
*/
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */
/* Make sure that pipeline is emptied */
mov r0, r0
mov r0, r0
mov pc, lr
ENTRY(ixp12x0_drain_readbuf)
mcr p15, 0, r0, c9, c0, 0 /* drain read buffer */
mov pc, lr
/*
* Information for the IXP12X0 cache clean/purge functions:
*
* * Virtual address of the memory region to use
* * Size of memory region
*/
.data
.global _C_LABEL(ixp12x0_cache_clean_addr)
_C_LABEL(ixp12x0_cache_clean_addr):
.word 0xf0000000
.global _C_LABEL(ixp12x0_cache_clean_size)
_C_LABEL(ixp12x0_cache_clean_size):
.word 0x00008000
.text
.Lixp12x0_cache_clean_addr:
.word _C_LABEL(ixp12x0_cache_clean_addr)
.Lixp12x0_cache_clean_size:
.word _C_LABEL(ixp12x0_cache_clean_size)

View File

@ -0,0 +1,316 @@
/* $NetBSD: cpufunc_asm_sa1.S,v 1.8 2002/08/17 16:36:32 thorpej Exp $ */
/*
* Copyright (c) 1997,1998 Mark Brinicombe.
* Copyright (c) 1997 Causality Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Causality Limited.
* 4. The name of Causality Limited may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* SA-1 assembly functions for CPU / MMU / TLB specific operations
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.Lblock_userspace_access:
.word _C_LABEL(block_userspace_access)
/*
* Functions to set the MMU Translation Table Base register
*
* We need to clean and flush the cache as it uses virtual
* addresses that are about to change.
*/
ENTRY(getttb)
mrc p15, 0, r0, c2, c0, 0
ENTRY(sa1_setttb)
#ifdef CACHE_CLEAN_BLOCK_INTR
mrs r3, cpsr_all
orr r1, r3, #(I32_bit | F32_bit)
msr cpsr_all, r1
#else
ldr r3, .Lblock_userspace_access
ldr r2, [r3]
orr r1, r2, #1
str r1, [r3]
#endif
stmfd sp!, {r0-r3, lr}
bl _C_LABEL(sa1_cache_cleanID)
ldmfd sp!, {r0-r3, lr}
mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ and BTB */
mcr p15, 0, r0, c7, c10, 4 /* drain write and fill buffer */
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLB */
/* The cleanID above means we only need to flush the I cache here */
mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ and BTB */
/* Make sure that pipeline is emptied */
mov r0, r0
mov r0, r0
#ifdef CACHE_CLEAN_BLOCK_INTR
msr cpsr_all, r3
#else
str r2, [r3]
#endif
mov pc, lr
/*
* TLB functions
*/
ENTRY(sa1_tlb_flushID_SE)
mcr p15, 0, r0, c8, c6, 1 /* flush D tlb single entry */
mcr p15, 0, r0, c8, c5, 0 /* flush I tlb */
mov pc, lr
/*
* Cache functions
*/
ENTRY(sa1_cache_flushID)
mcr p15, 0, r0, c7, c7, 0 /* flush I+D cache */
mov pc, lr
ENTRY(sa1_cache_flushI)
mcr p15, 0, r0, c7, c5, 0 /* flush I cache */
mov pc, lr
ENTRY(sa1_cache_flushD)
mcr p15, 0, r0, c7, c6, 0 /* flush D cache */
mov pc, lr
ENTRY(sa1_cache_flushD_SE)
mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
mov pc, lr
ENTRY(sa1_cache_cleanD_E)
mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
mov pc, lr
/*
* Information for the SA-1 cache clean/purge functions:
*
* * Virtual address of the memory region to use
* * Size of memory region
*/
.data
.global _C_LABEL(sa1_cache_clean_addr)
_C_LABEL(sa1_cache_clean_addr):
.word 0xf0000000
.global _C_LABEL(sa1_cache_clean_size)
_C_LABEL(sa1_cache_clean_size):
#if defined(CPU_SA1100) || defined(CPU_SA1110)
.word 0x00004000
#else
.word 0x00008000
#endif
.text
.Lsa1_cache_clean_addr:
.word _C_LABEL(sa1_cache_clean_addr)
.Lsa1_cache_clean_size:
.word _C_LABEL(sa1_cache_clean_size)
#ifdef CACHE_CLEAN_BLOCK_INTR
#define SA1_CACHE_CLEAN_BLOCK \
mrs r3, cpsr_all ; \
orr r0, r3, #(I32_bit | F32_bit) ; \
msr cpsr_all, r0
#define SA1_CACHE_CLEAN_UNBLOCK \
msr cpsr_all, r3
#else
#define SA1_CACHE_CLEAN_BLOCK \
ldr r3, .Lblock_userspace_access ; \
ldr ip, [r3] ; \
orr r0, ip, #1 ; \
str r0, [r3]
#define SA1_CACHE_CLEAN_UNBLOCK \
str ip, [r3]
#endif /* CACHE_CLEAN_BLOCK_INTR */
#ifdef DOUBLE_CACHE_CLEAN_BANK
#define SA1_DOUBLE_CACHE_CLEAN_BANK \
eor r0, r0, r1 ; \
str r0, [r2]
#else
#define SA1_DOUBLE_CACHE_CLEAN_BANK /* nothing */
#endif /* DOUBLE_CACHE_CLEAN_BANK */
#define SA1_CACHE_CLEAN_PROLOGUE \
SA1_CACHE_CLEAN_BLOCK ; \
ldr r2, .Lsa1_cache_clean_addr ; \
ldmia r2, {r0, r1} ; \
SA1_DOUBLE_CACHE_CLEAN_BANK
#define SA1_CACHE_CLEAN_EPILOGUE \
SA1_CACHE_CLEAN_UNBLOCK
ENTRY_NP(sa1_cache_syncI)
ENTRY_NP(sa1_cache_purgeID)
mcr p15, 0, r0, c7, c5, 0 /* flush I cache (D cleaned below) */
ENTRY_NP(sa1_cache_cleanID)
ENTRY_NP(sa1_cache_purgeD)
ENTRY(sa1_cache_cleanD)
SA1_CACHE_CLEAN_PROLOGUE
1: ldr r2, [r0], #32
subs r1, r1, #32
bne 1b
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
SA1_CACHE_CLEAN_EPILOGUE
mov pc, lr
ENTRY(sa1_cache_purgeID_E)
mcr p15, 0, r0, c7, c10, 1 /* clean dcache entry */
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mcr p15, 0, r0, c7, c5, 0 /* flush I cache */
mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
mov pc, lr
ENTRY(sa1_cache_purgeD_E)
mcr p15, 0, r0, c7, c10, 1 /* clean dcache entry */
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
mov pc, lr
/*
* Soft functions
*/
/* sa1_cache_syncI is identical to sa1_cache_purgeID */
ENTRY(sa1_cache_cleanID_rng)
ENTRY(sa1_cache_cleanD_rng)
cmp r1, #0x4000
bcs _C_LABEL(sa1_cache_cleanID)
and r2, r0, #0x1f
add r1, r1, r2
bic r0, r0, #0x1f
1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
add r0, r0, #32
subs r1, r1, #32
bhi 1b
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mov pc, lr
ENTRY(sa1_cache_purgeID_rng)
cmp r1, #0x4000
bcs _C_LABEL(sa1_cache_purgeID)
and r2, r0, #0x1f
add r1, r1, r2
bic r0, r0, #0x1f
1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
add r0, r0, #32
subs r1, r1, #32
bhi 1b
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mcr p15, 0, r0, c7, c5, 0 /* flush I cache */
mov pc, lr
ENTRY(sa1_cache_purgeD_rng)
cmp r1, #0x4000
bcs _C_LABEL(sa1_cache_purgeD)
and r2, r0, #0x1f
add r1, r1, r2
bic r0, r0, #0x1f
1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
add r0, r0, #32
subs r1, r1, #32
bhi 1b
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mov pc, lr
ENTRY(sa1_cache_syncI_rng)
cmp r1, #0x4000
bcs _C_LABEL(sa1_cache_syncI)
and r2, r0, #0x1f
add r1, r1, r2
bic r0, r0, #0x1f
1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
add r0, r0, #32
subs r1, r1, #32
bhi 1b
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mcr p15, 0, r0, c7, c5, 0 /* flush I cache */
mov pc, lr
/*
* Context switch.
*
* These is the CPU-specific parts of the context switcher cpu_switch()
* These functions actually perform the TTB reload.
*
* NOTE: Special calling convention
* r1, r4-r13 must be preserved
*/
#if defined(CPU_SA110)
ENTRY(sa110_context_switch)
/*
* CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
* Thus the data cache will contain only kernel data and the
* instruction cache will contain only kernel code, and all
* kernel mappings are shared by all processes.
*/
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */
/* Make sure that pipeline is emptied */
mov r0, r0
mov r0, r0
mov pc, lr
#endif

View File

@ -0,0 +1,125 @@
/* $NetBSD: cpufunc_asm_sa11x0.S,v 1.3 2002/08/17 16:36:32 thorpej Exp $ */
/*
* Copyright (c) 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.data
.global _C_LABEL(sa11x0_idle_mem)
_C_LABEL(sa11x0_idle_mem):
.word 0
.text
.align 5
/* We're now 32-byte aligned */
.Lsa11x0_idle_mem:
.word _C_LABEL(sa11x0_idle_mem) /* 1 */
/*
* sa11x0_cpusleep
*
* This is called when there is nothing on any of the run queues.
* We go into IDLE mode so that any IRQ or FIQ will awaken us.
*/
ENTRY(sa11x0_cpu_sleep)
ldr r1, .Lsa11x0_idle_mem /* get address of... */ /* 2 */
nop /* 3 */
ldr r1, [r1] /* ...non-cacheable page */ /* 4 */
nop /* 5 */
/*
* SA-1110 manual, 9.5.2.1 (Entering Idle Mode) says that
* to enter idle mode:
*
* * Disable clock switching
* * Issue load from non-cacheable address
* * Issue "wait for interrupt"
*
* The 3-insn sequence must reside in the first 3 words
* of a cache line.
*
* We must disable interrupts in the CPSR so that we can
* re-enable clock switching before servicing interrupts.
*/
mrs r3, cpsr_all /* 6 */
orr r2, r3, #(I32_bit|F32_bit) /* 7 */
msr cpsr_all, r2 /* 8 */
/* We're now 32-byte aligned */
mcr p15, 0, r0, c15, c2, 2 /* disable clock switching */
ldr r0, [r1] /* load from non-cacheable address */
mcr p15, 0, r0, c15, c8, 2 /* wait for interrupt */
mcr p15, 0, r0, c15, c1, 2 /* re-enable clock switching */
/* Restore interrupts (which will cause them to be serviced). */
msr cpsr_all, r3
mov pc, lr
/*
* This function is the same as sa110_context_switch for now, the plan
* is to make use of the process id register to avoid cache flushes.
*/
ENTRY(sa11x0_context_switch)
/*
* CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
* Thus the data cache will contain only kernel data and the
* instruction cache will contain only kernel code, and all
* kernel mappings are shared by all processes.
*/
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */
/* Make sure that pipeline is emptied */
mov r0, r0
mov r0, r0
mov pc, lr
ENTRY(sa11x0_drain_readbuf)
mcr p15, 0, r0, c9, c0, 0 /* drain read buffer */
mov pc, lr

View File

@ -0,0 +1,497 @@
/* $NetBSD: cpufunc_asm_xscale.S,v 1.16 2002/08/17 16:36:32 thorpej Exp $ */
/*
* Copyright (c) 2001, 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Allen Briggs and Jason R. Thorpe for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Copyright (c) 2001 Matt Thomas.
* Copyright (c) 1997,1998 Mark Brinicombe.
* Copyright (c) 1997 Causality Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Causality Limited.
* 4. The name of Causality Limited may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* XScale assembly functions for CPU / MMU / TLB specific operations
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* Size of the XScale core D-cache.
*/
#define DCACHE_SIZE 0x00008000
.Lblock_userspace_access:
.word _C_LABEL(block_userspace_access)
/*
* CPWAIT -- Canonical method to wait for CP15 update.
* From: Intel 80200 manual, section 2.3.3.
*
* NOTE: Clobbers the specified temp reg.
*/
#define CPWAIT_BRANCH \
sub pc, pc, #4
#define CPWAIT(tmp) \
mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\
mov tmp, tmp /* wait for it to complete */ ;\
CPWAIT_BRANCH /* branch to next insn */
#define CPWAIT_AND_RETURN_SHIFTER lsr #32
#define CPWAIT_AND_RETURN(tmp) \
mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\
/* Wait for it to complete and branch to the return address */ \
sub pc, lr, tmp, CPWAIT_AND_RETURN_SHIFTER
ENTRY(xscale_cpwait)
CPWAIT_AND_RETURN(r0)
/*
* We need a separate cpu_control() entry point, since we have to
* invalidate the Branch Target Buffer in the event the BPRD bit
* changes in the control register.
*/
ENTRY(xscale_control)
mrc p15, 0, r3, c1, c0, 0 /* Read the control register */
bic r2, r3, r0 /* Clear bits */
eor r2, r2, r1 /* XOR bits */
teq r2, r3 /* Only write if there was a change */
mcrne p15, 0, r0, c7, c5, 6 /* Invalidate the BTB */
mcrne p15, 0, r2, c1, c0, 0 /* Write new control register */
mov r0, r3 /* Return old value */
CPWAIT_AND_RETURN(r1)
/*
* Functions to set the MMU Translation Table Base register
*
* We need to clean and flush the cache as it uses virtual
* addresses that are about to change.
*/
ENTRY(xscale_setttb)
#ifdef CACHE_CLEAN_BLOCK_INTR
mrs r3, cpsr_all
orr r1, r3, #(I32_bit | F32_bit)
msr cpsr_all, r1
#else
ldr r3, .Lblock_userspace_access
ldr r2, [r3]
orr r1, r2, #1
str r1, [r3]
#endif
stmfd sp!, {r0-r3, lr}
bl _C_LABEL(xscale_cache_cleanID)
mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ and BTB */
mcr p15, 0, r0, c7, c10, 4 /* drain write and fill buffer */
CPWAIT(r0)
ldmfd sp!, {r0-r3, lr}
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLB */
/* The cleanID above means we only need to flush the I cache here */
mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ and BTB */
CPWAIT(r0)
#ifdef CACHE_CLEAN_BLOCK_INTR
msr cpsr_all, r3
#else
str r2, [r3]
#endif
mov pc, lr
/*
* TLB functions
*
* Note: We don't need to worry about issuing a CPWAIT after
* TLB operations, because we expect a pmap_update() to follow.
*/
ENTRY(xscale_tlb_flushID_SE)
mcr p15, 0, r0, c8, c6, 1 /* flush D tlb single entry */
mcr p15, 0, r0, c8, c5, 1 /* flush I tlb single entry */
mov pc, lr
/*
* Cache functions
*/
ENTRY(xscale_cache_flushID)
mcr p15, 0, r0, c7, c7, 0 /* flush I+D cache */
CPWAIT_AND_RETURN(r0)
ENTRY(xscale_cache_flushI)
mcr p15, 0, r0, c7, c5, 0 /* flush I cache */
CPWAIT_AND_RETURN(r0)
ENTRY(xscale_cache_flushD)
mcr p15, 0, r0, c7, c6, 0 /* flush D cache */
CPWAIT_AND_RETURN(r0)
ENTRY(xscale_cache_flushI_SE)
mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */
CPWAIT_AND_RETURN(r0)
ENTRY(xscale_cache_flushD_SE)
/*
* Errata (rev < 2): Must clean-dcache-line to an address
* before invalidate-dcache-line to an address, or dirty
* bits will not be cleared in the dcache array.
*/
mcr p15, 0, r0, c7, c10, 1
mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
CPWAIT_AND_RETURN(r0)
ENTRY(xscale_cache_cleanD_E)
mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
CPWAIT_AND_RETURN(r0)
/*
* Information for the XScale cache clean/purge functions:
*
* * Virtual address of the memory region to use
* * Size of memory region
*
* Note the virtual address for the Data cache clean operation
* does not need to be backed by physical memory, since no loads
* will actually be performed by the allocate-line operation.
*
* Note that the Mini-Data cache MUST be cleaned by executing
* loads from memory mapped into a region reserved exclusively
* for cleaning of the Mini-Data cache.
*/
.data
.global _C_LABEL(xscale_cache_clean_addr)
_C_LABEL(xscale_cache_clean_addr):
.word 0x00000000
.global _C_LABEL(xscale_cache_clean_size)
_C_LABEL(xscale_cache_clean_size):
.word DCACHE_SIZE
.global _C_LABEL(xscale_minidata_clean_addr)
_C_LABEL(xscale_minidata_clean_addr):
.word 0x00000000
.global _C_LABEL(xscale_minidata_clean_size)
_C_LABEL(xscale_minidata_clean_size):
.word 0x00000800
.text
.Lxscale_cache_clean_addr:
.word _C_LABEL(xscale_cache_clean_addr)
.Lxscale_cache_clean_size:
.word _C_LABEL(xscale_cache_clean_size)
.Lxscale_minidata_clean_addr:
.word _C_LABEL(xscale_minidata_clean_addr)
.Lxscale_minidata_clean_size:
.word _C_LABEL(xscale_minidata_clean_size)
#ifdef CACHE_CLEAN_BLOCK_INTR
#define XSCALE_CACHE_CLEAN_BLOCK \
mrs r3, cpsr_all ; \
orr r0, r3, #(I32_bit | F32_bit) ; \
msr cpsr_all, r0
#define XSCALE_CACHE_CLEAN_UNBLOCK \
msr cpsr_all, r3
#else
#define XSCALE_CACHE_CLEAN_BLOCK \
ldr r3, .Lblock_userspace_access ; \
ldr ip, [r3] ; \
orr r0, ip, #1 ; \
str r0, [r3]
#define XSCALE_CACHE_CLEAN_UNBLOCK \
str ip, [r3]
#endif /* CACHE_CLEAN_BLOCK_INTR */
#define XSCALE_CACHE_CLEAN_PROLOGUE \
XSCALE_CACHE_CLEAN_BLOCK ; \
ldr r2, .Lxscale_cache_clean_addr ; \
ldmia r2, {r0, r1} ; \
/* \
* BUG ALERT! \
* \
* The XScale core has a strange cache eviction bug, which \
* requires us to use 2x the cache size for the cache clean \
* and for that area to be aligned to 2 * cache size. \
* \
* The work-around is to use 2 areas for cache clean, and to \
* alternate between them whenever this is done. No one knows \
* why the work-around works (mmm!). \
*/ \
eor r0, r0, #(DCACHE_SIZE) ; \
str r0, [r2] ; \
add r0, r0, r1
#define XSCALE_CACHE_CLEAN_EPILOGUE \
XSCALE_CACHE_CLEAN_UNBLOCK
ENTRY_NP(xscale_cache_syncI)
ENTRY_NP(xscale_cache_purgeID)
mcr p15, 0, r0, c7, c5, 0 /* flush I cache (D cleaned below) */
ENTRY_NP(xscale_cache_cleanID)
ENTRY_NP(xscale_cache_purgeD)
ENTRY(xscale_cache_cleanD)
XSCALE_CACHE_CLEAN_PROLOGUE
1: subs r0, r0, #32
mcr p15, 0, r0, c7, c2, 5 /* allocate cache line */
subs r1, r1, #32
bne 1b
CPWAIT(r0)
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
CPWAIT(r0)
XSCALE_CACHE_CLEAN_EPILOGUE
mov pc, lr
/*
* Clean the mini-data cache.
*
* It's expected that we only use the mini-data cache for
* kernel addresses, so there is no need to purge it on
* context switch, and no need to prevent userspace access
* while we clean it.
*/
ENTRY(xscale_cache_clean_minidata)
ldr r2, .Lxscale_minidata_clean_addr
ldmia r2, {r0, r1}
1: ldr r3, [r0], #32
subs r1, r1, #32
bne 1b
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
CPWAIT_AND_RETURN(r1)
ENTRY(xscale_cache_purgeID_E)
mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
CPWAIT(r1)
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */
mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
CPWAIT_AND_RETURN(r1)
ENTRY(xscale_cache_purgeD_E)
mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
CPWAIT(r1)
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
CPWAIT_AND_RETURN(r1)
/*
* Soft functions
*/
/* xscale_cache_syncI is identical to xscale_cache_purgeID */
ENTRY(xscale_cache_cleanID_rng)
ENTRY(xscale_cache_cleanD_rng)
cmp r1, #0x4000
bcs _C_LABEL(xscale_cache_cleanID)
and r2, r0, #0x1f
add r1, r1, r2
bic r0, r0, #0x1f
1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
add r0, r0, #32
subs r1, r1, #32
bhi 1b
CPWAIT(r0)
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
CPWAIT_AND_RETURN(r0)
ENTRY(xscale_cache_purgeID_rng)
cmp r1, #0x4000
bcs _C_LABEL(xscale_cache_purgeID)
and r2, r0, #0x1f
add r1, r1, r2
bic r0, r0, #0x1f
1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */
add r0, r0, #32
subs r1, r1, #32
bhi 1b
CPWAIT(r0)
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
CPWAIT_AND_RETURN(r0)
ENTRY(xscale_cache_purgeD_rng)
cmp r1, #0x4000
bcs _C_LABEL(xscale_cache_purgeD)
and r2, r0, #0x1f
add r1, r1, r2
bic r0, r0, #0x1f
1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
add r0, r0, #32
subs r1, r1, #32
bhi 1b
CPWAIT(r0)
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
CPWAIT_AND_RETURN(r0)
ENTRY(xscale_cache_syncI_rng)
cmp r1, #0x4000
bcs _C_LABEL(xscale_cache_syncI)
and r2, r0, #0x1f
add r1, r1, r2
bic r0, r0, #0x1f
1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */
add r0, r0, #32
subs r1, r1, #32
bhi 1b
CPWAIT(r0)
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
CPWAIT_AND_RETURN(r0)
ENTRY(xscale_cache_flushD_rng)
and r2, r0, #0x1f
add r1, r1, r2
bic r0, r0, #0x1f
1: mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
add r0, r0, #32
subs r1, r1, #32
bhi 1b
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
CPWAIT_AND_RETURN(r0)
/*
* Context switch.
*
* These is the CPU-specific parts of the context switcher cpu_switch()
* These functions actually perform the TTB reload.
*
* NOTE: Special calling convention
* r1, r4-r13 must be preserved
*/
ENTRY(xscale_context_switch)
/*
* CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
* Thus the data cache will contain only kernel data and the
* instruction cache will contain only kernel code, and all
* kernel mappings are shared by all processes.
*/
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */
CPWAIT_AND_RETURN(r0)
/*
* xscale_cpu_sleep
*
* This is called when there is nothing on any of the run queues.
* We go into IDLE mode so that any IRQ or FIQ will awaken us.
*
* If this is called with anything other than ARM_SLEEP_MODE_IDLE,
* ignore it.
*/
ENTRY(xscale_cpu_sleep)
tst r0, #0x00000000
bne 1f
mov r0, #0x1
mcr p14, 0, r0, c7, c0, 0
1:
mov pc, lr

50
sys/arm/arm/critical.c Normal file
View File

@ -0,0 +1,50 @@
/*-
* Copyright (c) 2002 Matthew Dillon. All Rights Reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/signalvar.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/pcpu.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/ucontext.h>
#include <machine/clock.h>
#include <machine/critical.h>
/*
* cpu_critical_fork_exit() - cleanup after fork
*/
void
cpu_critical_fork_exit(void)
{
}

79
sys/arm/arm/db_disasm.c Normal file
View File

@ -0,0 +1,79 @@
/* $NetBSD: db_disasm.c,v 1.4 2003/07/15 00:24:38 lukem Exp $ */
/*
* Copyright (c) 1996 Mark Brinicombe.
* Copyright (c) 1996 Brini.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <machine/db_machdep.h>
#include <ddb/ddb.h>
#include <ddb/db_access.h>
#include <ddb/db_sym.h>
#include <machine/disassem.h>
/* Glue code to interface db_disasm to the generic ARM disassembler */
static u_int db_disasm_read_word(u_int);
static void db_disasm_printaddr(u_int);
static const disasm_interface_t db_disasm_interface = {
db_disasm_read_word,
db_disasm_printaddr,
db_printf
};
static u_int
db_disasm_read_word(u_int address)
{
return db_get_value(address, 4, 0);
}
static void
db_disasm_printaddr(u_int address)
{
db_printsym((db_addr_t)address, DB_STGY_ANY);
}
vm_offset_t
db_disasm(vm_offset_t loc, boolean_t altfmt)
{
return disasm(&db_disasm_interface, loc, altfmt);
}
/* End of db_disasm.c */

334
sys/arm/arm/db_interface.c Normal file
View File

@ -0,0 +1,334 @@
/* $NetBSD: db_interface.c,v 1.33 2003/08/25 04:51:10 mrg Exp $ */
/*
* Copyright (c) 1996 Scott K. Stevens
*
* Mach Operating System
* Copyright (c) 1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
* From: db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
*/
/*
* Interface to new debugger.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/systm.h> /* just for boothowto */
#include <sys/exec.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_extern.h>
#include <machine/db_machdep.h>
#include <machine/katelib.h>
#include <machine/vmparam.h>
#include <machine/cpu.h>
#include <ddb/ddb.h>
#include <ddb/db_access.h>
#include <ddb/db_command.h>
#include <ddb/db_output.h>
#include <ddb/db_variables.h>
#include <ddb/db_sym.h>
#include <sys/cons.h>
static int nil;
db_regs_t ddb_regs;
int db_access_und_sp (struct db_variable *, db_expr_t *, int);
int db_access_abt_sp (struct db_variable *, db_expr_t *, int);
int db_access_irq_sp (struct db_variable *, db_expr_t *, int);
u_int db_fetch_reg (int, db_regs_t *);
int db_trapper __P((u_int, u_int, trapframe_t *, int));
struct db_variable db_regs[] = {
{ "spsr", (int *)&DDB_REGS->tf_spsr, FCN_NULL, },
{ "r0", (int *)&DDB_REGS->tf_r0, FCN_NULL, },
{ "r1", (int *)&DDB_REGS->tf_r1, FCN_NULL, },
{ "r2", (int *)&DDB_REGS->tf_r2, FCN_NULL, },
{ "r3", (int *)&DDB_REGS->tf_r3, FCN_NULL, },
{ "r4", (int *)&DDB_REGS->tf_r4, FCN_NULL, },
{ "r5", (int *)&DDB_REGS->tf_r5, FCN_NULL, },
{ "r6", (int *)&DDB_REGS->tf_r6, FCN_NULL, },
{ "r7", (int *)&DDB_REGS->tf_r7, FCN_NULL, },
{ "r8", (int *)&DDB_REGS->tf_r8, FCN_NULL, },
{ "r9", (int *)&DDB_REGS->tf_r9, FCN_NULL, },
{ "r10", (int *)&DDB_REGS->tf_r10, FCN_NULL, },
{ "r11", (int *)&DDB_REGS->tf_r11, FCN_NULL, },
{ "r12", (int *)&DDB_REGS->tf_r12, FCN_NULL, },
{ "usr_sp", (int *)&DDB_REGS->tf_usr_sp, FCN_NULL, },
{ "usr_lr", (int *)&DDB_REGS->tf_usr_lr, FCN_NULL, },
{ "svc_sp", (int *)&DDB_REGS->tf_svc_sp, FCN_NULL, },
{ "svc_lr", (int *)&DDB_REGS->tf_svc_lr, FCN_NULL, },
{ "pc", (int *)&DDB_REGS->tf_pc, FCN_NULL, },
{ "und_sp", &nil, db_access_und_sp, },
{ "abt_sp", &nil, db_access_abt_sp, },
{ "irq_sp", &nil, db_access_irq_sp, },
};
struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
int db_active = 0;
int
db_access_und_sp(struct db_variable *vp, db_expr_t *valp, int rw)
{
if (rw == DB_VAR_GET)
*valp = get_stackptr(PSR_UND32_MODE);
return(0);
}
int
db_access_abt_sp(struct db_variable *vp, db_expr_t *valp, int rw)
{
if (rw == DB_VAR_GET)
*valp = get_stackptr(PSR_ABT32_MODE);
return(0);
}
int
db_access_irq_sp(struct db_variable *vp, db_expr_t *valp, int rw)
{
if (rw == DB_VAR_GET)
*valp = get_stackptr(PSR_IRQ32_MODE);
return(0);
}
#ifdef DDB
/*
* kdb_trap - field a TRACE or BPT trap
*/
int
kdb_trap(int type, db_regs_t *regs)
{
int s;
switch (type) {
case T_BREAKPOINT: /* breakpoint */
case -1: /* keyboard interrupt */
break;
default:
break;
}
/* Should switch to kdb`s own stack here. */
ddb_regs = *regs;
s = splhigh();
db_active++;
db_trap(type, 0/*code*/);
db_active--;
splx(s);
*regs = ddb_regs;
return (1);
}
#endif
void
db_show_mdpcpu(struct pcpu *pc)
{
}
int
db_validate_address(vm_offset_t addr)
{
struct proc *p = curproc;
struct pmap *pmap;
if (!p || !p->p_vmspace || !p->p_vmspace->vm_map.pmap ||
#ifndef ARM32_NEW_VM_LAYOUT
addr >= VM_MAXUSER_ADDRESS
#else
addr >= VM_MIN_KERNEL_ADDRESS
#endif
)
pmap = pmap_kernel();
else
pmap = p->p_vmspace->vm_map.pmap;
return (pmap_extract(pmap, addr) == FALSE);
}
/*
* Read bytes from kernel address space for debugger.
*/
void
db_read_bytes(addr, size, data)
vm_offset_t addr;
size_t size;
char *data;
{
char *src = (char *)addr;
if (db_validate_address((u_int)src)) {
db_printf("address %p is invalid\n", src);
return;
}
if (size == 4 && (addr & 3) == 0 && ((uintptr_t)data & 3) == 0) {
*((int*)data) = *((int*)src);
return;
}
if (size == 2 && (addr & 1) == 0 && ((uintptr_t)data & 1) == 0) {
*((short*)data) = *((short*)src);
return;
}
while (size-- > 0) {
if (db_validate_address((u_int)src)) {
db_printf("address %p is invalid\n", src);
return;
}
*data++ = *src++;
}
}
/*
* Write bytes to kernel address space for debugger.
*/
void
db_write_bytes(vm_offset_t addr, size_t size, char *data)
{
char *dst;
size_t loop;
/* If any part is in kernel text, use db_write_text() */
if (addr >= (vm_offset_t) btext && addr < (vm_offset_t) etext) {
return;
}
dst = (char *)addr;
if (db_validate_address((u_int)dst)) {
db_printf("address %p is invalid\n", dst);
return;
}
if (size == 4 && (addr & 3) == 0 && ((uintptr_t)data & 3) == 0)
*((int*)dst) = *((int*)data);
else
if (size == 2 && (addr & 1) == 0 && ((uintptr_t)data & 1) == 0)
*((short*)dst) = *((short*)data);
else {
loop = size;
while (loop-- > 0) {
if (db_validate_address((u_int)dst)) {
db_printf("address %p is invalid\n", dst);
return;
}
*dst++ = *data++;
}
}
/* make sure the caches and memory are in sync */
cpu_icache_sync_range(addr, size);
/* In case the current page tables have been modified ... */
cpu_tlb_flushID();
cpu_cpwait();
}
#ifdef DDB
void
Debugger(const char *msg)
{
db_printf("Debugger(\"%s\")\n", msg);
__asm(".word 0xe7ffffff");
}
int
db_trapper(u_int addr, u_int inst, trapframe_t *frame, int fault_code)
{
if (fault_code == 0) {
if ((inst & ~INSN_COND_MASK) == (BKPT_INST & ~INSN_COND_MASK))
kdb_trap(T_BREAKPOINT, frame);
else
kdb_trap(-1, frame);
} else
return (1);
return (0);
}
extern u_int end;
#endif
u_int
db_fetch_reg(int reg, db_regs_t *db_regs)
{
switch (reg) {
case 0:
return (db_regs->tf_r0);
case 1:
return (db_regs->tf_r1);
case 2:
return (db_regs->tf_r2);
case 3:
return (db_regs->tf_r3);
case 4:
return (db_regs->tf_r4);
case 5:
return (db_regs->tf_r5);
case 6:
return (db_regs->tf_r6);
case 7:
return (db_regs->tf_r7);
case 8:
return (db_regs->tf_r8);
case 9:
return (db_regs->tf_r9);
case 10:
return (db_regs->tf_r10);
case 11:
return (db_regs->tf_r11);
case 12:
return (db_regs->tf_r12);
case 13:
return (db_regs->tf_svc_sp);
case 14:
return (db_regs->tf_svc_lr);
case 15:
return (db_regs->tf_pc);
default:
panic("db_fetch_reg: botch");
}
}

250
sys/arm/arm/db_trace.c Normal file
View File

@ -0,0 +1,250 @@
/* $NetBSD: db_trace.c,v 1.8 2003/01/17 22:28:48 thorpej Exp $ */
/*
* Copyright (c) 2000, 2001 Ben Harris
* Copyright (c) 1996 Scott K. Stevens
*
* Mach Operating System
* Copyright (c) 1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <machine/armreg.h>
#include <machine/asm.h>
#include <machine/cpufunc.h>
#include <machine/db_machdep.h>
#include <machine/vmparam.h>
#include <ddb/ddb.h>
#include <ddb/db_access.h>
#include <ddb/db_sym.h>
#include <ddb/db_output.h>
#define INKERNEL(va) (((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS)
int db_md_set_watchpoint(db_expr_t addr, db_expr_t size);
int db_md_clr_watchpoint(db_expr_t addr, db_expr_t size);
void db_md_list_watchpoints(void);
/*
* APCS stack frames are awkward beasts, so I don't think even trying to use
* a structure to represent them is a good idea.
*
* Here's the diagram from the APCS. Increasing address is _up_ the page.
*
* save code pointer [fp] <- fp points to here
* return link value [fp, #-4]
* return sp value [fp, #-8]
* return fp value [fp, #-12]
* [saved v7 value]
* [saved v6 value]
* [saved v5 value]
* [saved v4 value]
* [saved v3 value]
* [saved v2 value]
* [saved v1 value]
* [saved a4 value]
* [saved a3 value]
* [saved a2 value]
* [saved a1 value]
*
* The save code pointer points twelve bytes beyond the start of the
* code sequence (usually a single STM) that created the stack frame.
* We have to disassemble it if we want to know which of the optional
* fields are actually present.
*/
#define FR_SCP (0)
#define FR_RLV (-1)
#define FR_RSP (-2)
#define FR_RFP (-3)
void
db_stack_trace_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
char *modif;
{
u_int32_t *frame, *lastframe;
c_db_sym_t sym;
db_expr_t pc;
char c, *cp = modif;
const char *name;
db_expr_t value;
db_expr_t offset;
boolean_t kernel_only = TRUE;
boolean_t trace_thread = FALSE;
int scp_offset;
while ((c = *cp++) != 0) {
if (c == 'u')
kernel_only = FALSE;
if (c == 't')
trace_thread = TRUE;
}
if (!have_addr)
frame = (u_int32_t *)(DDB_REGS->tf_r11);
else {
if (trace_thread) {
struct proc *p;
struct thread *td;
pid_t pid = (pid_t)addr;
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_pid == pid)
break;
}
if (p == NULL) {
db_printf("not found\n");
return;
}
if (!(p->p_sflag & PS_INMEM)) {
db_printf("swapped out\n");
return;
}
td = FIRST_THREAD_IN_PROC(p);
frame = (u_int32_t *)(td->td_pcb->un_32.pcb32_r11);
db_printf("at %p\n", frame);
} else
frame = (u_int32_t *)(addr);
}
lastframe = NULL;
scp_offset = -(get_pc_str_offset() >> 2);
while (count-- && frame != NULL) {
db_addr_t scp;
u_int32_t savecode;
int r;
u_int32_t *rp;
const char *sep;
/*
* In theory, the SCP isn't guaranteed to be in the function
* that generated the stack frame. We hope for the best.
*/
#ifdef __PROG26
scp = frame[FR_SCP] & R15_PC;
#else
scp = frame[FR_SCP];
#endif
db_printsym(scp, DB_STGY_PROC);
db_printf("\n\t");
pc = ddb_regs.tf_pc;
sym = db_search_symbol(pc, DB_STGY_ANY, &offset);
if (sym == C_DB_SYM_NULL) {
value = 0;
name = "(null)";
} else
db_symbol_values(sym, &name, &value);
db_printf("%s() at ", name);
db_printsym(pc, DB_STGY_PROC);
db_printf("\n");
#ifdef __PROG26
db_printf("scp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV] & R15_PC);
db_printsym(frame[FR_RLV] & R15_PC, DB_STGY_PROC);
db_printf(")\n");
#else
db_printf("scp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV]);
db_printsym(frame[FR_RLV], DB_STGY_PROC);
db_printf(")\n");
#endif
db_printf("\trsp=0x%08x rfp=0x%08x", frame[FR_RSP], frame[FR_RFP]);
savecode = ((u_int32_t *)scp)[scp_offset];
if ((savecode & 0x0e100000) == 0x08000000) {
/* Looks like an STM */
rp = frame - 4;
sep = "\n\t";
for (r = 10; r >= 0; r--) {
if (savecode & (1 << r)) {
db_printf("%sr%d=0x%08x",
sep, r, *rp--);
sep = (frame - rp) % 4 == 2 ?
"\n\t" : " ";
}
}
}
db_printf("\n");
/*
* Switch to next frame up
*/
if (frame[FR_RFP] == 0)
break; /* Top of stack */
lastframe = frame;
frame = (u_int32_t *)(frame[FR_RFP]);
if (INKERNEL((int)frame)) {
/* staying in kernel */
if (frame <= lastframe) {
db_printf("Bad frame pointer: %p\n", frame);
break;
}
} else if (INKERNEL((int)lastframe)) {
/* switch from user to kernel */
if (kernel_only)
break; /* kernel stack only */
} else {
/* in user */
if (frame <= lastframe) {
db_printf("Bad user frame pointer: %p\n",
frame);
break;
}
}
}
}
/* XXX stubs */
void
db_md_list_watchpoints()
{
}
int
db_md_clr_watchpoint(db_expr_t addr, db_expr_t size)
{
return (0);
}
int
db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
{
return (0);
}
void
db_print_backtrace(void)
{
db_stack_trace_cmd((db_expr_t)__builtin_frame_address(0), 1, -1, NULL);
}

681
sys/arm/arm/disassem.c Normal file
View File

@ -0,0 +1,681 @@
/* $NetBSD: disassem.c,v 1.14 2003/03/27 16:58:36 mycroft Exp $ */
/*
* Copyright (c) 1996 Mark Brinicombe.
* Copyright (c) 1996 Brini.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* db_disasm.c
*
* Kernel disassembler
*
* Created : 10/02/96
*
* Structured after the sparc/sparc/db_disasm.c by David S. Miller &
* Paul Kranenburg
*
* This code is not complete. Not all instructions are disassembled.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <machine/disassem.h>
#include <machine/armreg.h>
#include <ddb/ddb.h>
/*
* General instruction format
*
* insn[cc][mod] [operands]
*
* Those fields with an uppercase format code indicate that the field
* follows directly after the instruction before the separator i.e.
* they modify the instruction rather than just being an operand to
* the instruction. The only exception is the writeback flag which
* follows a operand.
*
*
* 2 - print Operand 2 of a data processing instruction
* d - destination register (bits 12-15)
* n - n register (bits 16-19)
* s - s register (bits 8-11)
* o - indirect register rn (bits 16-19) (used by swap)
* m - m register (bits 0-3)
* a - address operand of ldr/str instruction
* l - register list for ldm/stm instruction
* f - 1st fp operand (register) (bits 12-14)
* g - 2nd fp operand (register) (bits 16-18)
* h - 3rd fp operand (register/immediate) (bits 0-4)
* b - branch address
* t - thumb branch address (bits 24, 0-23)
* k - breakpoint comment (bits 0-3, 8-19)
* X - block transfer type
* Y - block transfer type (r13 base)
* c - comment field bits(0-23)
* p - saved or current status register
* F - PSR transfer fields
* D - destination-is-r15 (P) flag on TST, TEQ, CMP, CMN
* L - co-processor transfer size
* S - set status flag
* P - fp precision
* Q - fp precision (for ldf/stf)
* R - fp rounding
* v - co-processor data transfer registers + addressing mode
* W - writeback flag
* x - instruction in hex
* # - co-processor number
* y - co-processor data processing registers
* z - co-processor register transfer registers
*/
struct arm32_insn {
u_int mask;
u_int pattern;
char* name;
char* format;
};
static const struct arm32_insn arm32_i[] = {
{ 0x0fffffff, 0x0ff00000, "imb", "c" }, /* Before swi */
{ 0x0fffffff, 0x0ff00001, "imbrange", "c" }, /* Before swi */
{ 0x0f000000, 0x0f000000, "swi", "c" },
{ 0xfe000000, 0xfa000000, "blx", "t" }, /* Before b and bl */
{ 0x0f000000, 0x0a000000, "b", "b" },
{ 0x0f000000, 0x0b000000, "bl", "b" },
{ 0x0fe000f0, 0x00000090, "mul", "Snms" },
{ 0x0fe000f0, 0x00200090, "mla", "Snmsd" },
{ 0x0fe000f0, 0x00800090, "umull", "Sdnms" },
{ 0x0fe000f0, 0x00c00090, "smull", "Sdnms" },
{ 0x0fe000f0, 0x00a00090, "umlal", "Sdnms" },
{ 0x0fe000f0, 0x00e00090, "smlal", "Sdnms" },
{ 0x0d700000, 0x04200000, "strt", "daW" },
{ 0x0d700000, 0x04300000, "ldrt", "daW" },
{ 0x0d700000, 0x04600000, "strbt", "daW" },
{ 0x0d700000, 0x04700000, "ldrbt", "daW" },
{ 0x0c500000, 0x04000000, "str", "daW" },
{ 0x0c500000, 0x04100000, "ldr", "daW" },
{ 0x0c500000, 0x04400000, "strb", "daW" },
{ 0x0c500000, 0x04500000, "ldrb", "daW" },
{ 0x0e1f0000, 0x080d0000, "stm", "YnWl" },/* separate out r13 base */
{ 0x0e1f0000, 0x081d0000, "ldm", "YnWl" },/* separate out r13 base */
{ 0x0e100000, 0x08000000, "stm", "XnWl" },
{ 0x0e100000, 0x08100000, "ldm", "XnWl" },
{ 0x0e1000f0, 0x00100090, "ldrb", "de" },
{ 0x0e1000f0, 0x00000090, "strb", "de" },
{ 0x0e1000f0, 0x001000d0, "ldrsb", "de" },
{ 0x0e1000f0, 0x001000b0, "ldrh", "de" },
{ 0x0e1000f0, 0x000000b0, "strh", "de" },
{ 0x0e1000f0, 0x001000f0, "ldrsh", "de" },
{ 0x0f200090, 0x00200090, "und", "x" }, /* Before data processing */
{ 0x0e1000d0, 0x000000d0, "und", "x" }, /* Before data processing */
{ 0x0ff00ff0, 0x01000090, "swp", "dmo" },
{ 0x0ff00ff0, 0x01400090, "swpb", "dmo" },
{ 0x0fbf0fff, 0x010f0000, "mrs", "dp" }, /* Before data processing */
{ 0x0fb0fff0, 0x0120f000, "msr", "pFm" },/* Before data processing */
{ 0x0fb0f000, 0x0320f000, "msr", "pF2" },/* Before data processing */
{ 0x0ffffff0, 0x012fff10, "bx", "m" },
{ 0x0fff0ff0, 0x016f0f10, "clz", "dm" },
{ 0x0ffffff0, 0x012fff30, "blx", "m" },
{ 0xfff000f0, 0xe1200070, "bkpt", "k" },
{ 0x0de00000, 0x00000000, "and", "Sdn2" },
{ 0x0de00000, 0x00200000, "eor", "Sdn2" },
{ 0x0de00000, 0x00400000, "sub", "Sdn2" },
{ 0x0de00000, 0x00600000, "rsb", "Sdn2" },
{ 0x0de00000, 0x00800000, "add", "Sdn2" },
{ 0x0de00000, 0x00a00000, "adc", "Sdn2" },
{ 0x0de00000, 0x00c00000, "sbc", "Sdn2" },
{ 0x0de00000, 0x00e00000, "rsc", "Sdn2" },
{ 0x0df00000, 0x01100000, "tst", "Dn2" },
{ 0x0df00000, 0x01300000, "teq", "Dn2" },
{ 0x0de00000, 0x01400000, "cmp", "Dn2" },
{ 0x0de00000, 0x01600000, "cmn", "Dn2" },
{ 0x0de00000, 0x01800000, "orr", "Sdn2" },
{ 0x0de00000, 0x01a00000, "mov", "Sd2" },
{ 0x0de00000, 0x01c00000, "bic", "Sdn2" },
{ 0x0de00000, 0x01e00000, "mvn", "Sd2" },
{ 0x0ff08f10, 0x0e000100, "adf", "PRfgh" },
{ 0x0ff08f10, 0x0e100100, "muf", "PRfgh" },
{ 0x0ff08f10, 0x0e200100, "suf", "PRfgh" },
{ 0x0ff08f10, 0x0e300100, "rsf", "PRfgh" },
{ 0x0ff08f10, 0x0e400100, "dvf", "PRfgh" },
{ 0x0ff08f10, 0x0e500100, "rdf", "PRfgh" },
{ 0x0ff08f10, 0x0e600100, "pow", "PRfgh" },
{ 0x0ff08f10, 0x0e700100, "rpw", "PRfgh" },
{ 0x0ff08f10, 0x0e800100, "rmf", "PRfgh" },
{ 0x0ff08f10, 0x0e900100, "fml", "PRfgh" },
{ 0x0ff08f10, 0x0ea00100, "fdv", "PRfgh" },
{ 0x0ff08f10, 0x0eb00100, "frd", "PRfgh" },
{ 0x0ff08f10, 0x0ec00100, "pol", "PRfgh" },
{ 0x0f008f10, 0x0e000100, "fpbop", "PRfgh" },
{ 0x0ff08f10, 0x0e008100, "mvf", "PRfh" },
{ 0x0ff08f10, 0x0e108100, "mnf", "PRfh" },
{ 0x0ff08f10, 0x0e208100, "abs", "PRfh" },
{ 0x0ff08f10, 0x0e308100, "rnd", "PRfh" },
{ 0x0ff08f10, 0x0e408100, "sqt", "PRfh" },
{ 0x0ff08f10, 0x0e508100, "log", "PRfh" },
{ 0x0ff08f10, 0x0e608100, "lgn", "PRfh" },
{ 0x0ff08f10, 0x0e708100, "exp", "PRfh" },
{ 0x0ff08f10, 0x0e808100, "sin", "PRfh" },
{ 0x0ff08f10, 0x0e908100, "cos", "PRfh" },
{ 0x0ff08f10, 0x0ea08100, "tan", "PRfh" },
{ 0x0ff08f10, 0x0eb08100, "asn", "PRfh" },
{ 0x0ff08f10, 0x0ec08100, "acs", "PRfh" },
{ 0x0ff08f10, 0x0ed08100, "atn", "PRfh" },
{ 0x0f008f10, 0x0e008100, "fpuop", "PRfh" },
{ 0x0e100f00, 0x0c000100, "stf", "QLv" },
{ 0x0e100f00, 0x0c100100, "ldf", "QLv" },
{ 0x0ff00f10, 0x0e000110, "flt", "PRgd" },
{ 0x0ff00f10, 0x0e100110, "fix", "PRdh" },
{ 0x0ff00f10, 0x0e200110, "wfs", "d" },
{ 0x0ff00f10, 0x0e300110, "rfs", "d" },
{ 0x0ff00f10, 0x0e400110, "wfc", "d" },
{ 0x0ff00f10, 0x0e500110, "rfc", "d" },
{ 0x0ff0ff10, 0x0e90f110, "cmf", "PRgh" },
{ 0x0ff0ff10, 0x0eb0f110, "cnf", "PRgh" },
{ 0x0ff0ff10, 0x0ed0f110, "cmfe", "PRgh" },
{ 0x0ff0ff10, 0x0ef0f110, "cnfe", "PRgh" },
{ 0xff100010, 0xfe000010, "mcr2", "#z" },
{ 0x0f100010, 0x0e000010, "mcr", "#z" },
{ 0xff100010, 0xfe100010, "mrc2", "#z" },
{ 0x0f100010, 0x0e100010, "mrc", "#z" },
{ 0xff000010, 0xfe000000, "cdp2", "#y" },
{ 0x0f000010, 0x0e000000, "cdp", "#y" },
{ 0xfe100090, 0xfc100000, "ldc2", "L#v" },
{ 0x0e100090, 0x0c100000, "ldc", "L#v" },
{ 0xfe100090, 0xfc000000, "stc2", "L#v" },
{ 0x0e100090, 0x0c000000, "stc", "L#v" },
{ 0x00000000, 0x00000000, NULL, NULL }
};
static char const arm32_insn_conditions[][4] = {
"eq", "ne", "cs", "cc",
"mi", "pl", "vs", "vc",
"hi", "ls", "ge", "lt",
"gt", "le", "", "nv"
};
static char const insn_block_transfers[][4] = {
"da", "ia", "db", "ib"
};
static char const insn_stack_block_transfers[][4] = {
"ed", "ea", "fd", "fa"
};
static char const op_shifts[][4] = {
"lsl", "lsr", "asr", "ror"
};
static char const insn_fpa_rounding[][2] = {
"", "p", "m", "z"
};
static char const insn_fpa_precision[][2] = {
"s", "d", "e", "p"
};
static char const insn_fpaconstants[][8] = {
"0.0", "1.0", "2.0", "3.0",
"4.0", "5.0", "0.5", "10.0"
};
#define insn_condition(x) arm32_insn_conditions[(x >> 28) & 0x0f]
#define insn_blktrans(x) insn_block_transfers[(x >> 23) & 3]
#define insn_stkblktrans(x) insn_stack_block_transfers[(x >> 23) & 3]
#define op2_shift(x) op_shifts[(x >> 5) & 3]
#define insn_fparnd(x) insn_fpa_rounding[(x >> 5) & 0x03]
#define insn_fpaprec(x) insn_fpa_precision[(((x >> 18) & 2)|(x >> 7)) & 1]
#define insn_fpaprect(x) insn_fpa_precision[(((x >> 21) & 2)|(x >> 15)) & 1]
#define insn_fpaimm(x) insn_fpaconstants[x & 0x07]
/* Local prototypes */
static void disasm_register_shift(const disasm_interface_t *di, u_int insn);
static void disasm_print_reglist(const disasm_interface_t *di, u_int insn);
static void disasm_insn_ldrstr(const disasm_interface_t *di, u_int insn,
u_int loc);
static void disasm_insn_ldrhstrh(const disasm_interface_t *di, u_int insn,
u_int loc);
static void disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn,
u_int loc);
static u_int disassemble_readword(u_int address);
static void disassemble_printaddr(u_int address);
vm_offset_t
disasm(const disasm_interface_t *di, vm_offset_t loc, int altfmt)
{
struct arm32_insn *i_ptr = (struct arm32_insn *)&arm32_i;
u_int insn;
int matchp;
int branch;
char* f_ptr;
int fmt;
fmt = 0;
matchp = 0;
insn = di->di_readword(loc);
/* di->di_printf("loc=%08x insn=%08x : ", loc, insn);*/
while (i_ptr->name) {
if ((insn & i_ptr->mask) == i_ptr->pattern) {
matchp = 1;
break;
}
i_ptr++;
}
if (!matchp) {
di->di_printf("und%s\t%08x\n", insn_condition(insn), insn);
return(loc + INSN_SIZE);
}
/* If instruction forces condition code, don't print it. */
if ((i_ptr->mask & 0xf0000000) == 0xf0000000)
di->di_printf("%s", i_ptr->name);
else
di->di_printf("%s%s", i_ptr->name, insn_condition(insn));
f_ptr = i_ptr->format;
/* Insert tab if there are no instruction modifiers */
if (*(f_ptr) < 'A' || *(f_ptr) > 'Z') {
++fmt;
di->di_printf("\t");
}
while (*f_ptr) {
switch (*f_ptr) {
/* 2 - print Operand 2 of a data processing instruction */
case '2':
if (insn & 0x02000000) {
int rotate= ((insn >> 7) & 0x1e);
di->di_printf("#0x%08x",
(insn & 0xff) << (32 - rotate) |
(insn & 0xff) >> rotate);
} else {
disasm_register_shift(di, insn);
}
break;
/* d - destination register (bits 12-15) */
case 'd':
di->di_printf("r%d", ((insn >> 12) & 0x0f));
break;
/* D - insert 'p' if Rd is R15 */
case 'D':
if (((insn >> 12) & 0x0f) == 15)
di->di_printf("p");
break;
/* n - n register (bits 16-19) */
case 'n':
di->di_printf("r%d", ((insn >> 16) & 0x0f));
break;
/* s - s register (bits 8-11) */
case 's':
di->di_printf("r%d", ((insn >> 8) & 0x0f));
break;
/* o - indirect register rn (bits 16-19) (used by swap) */
case 'o':
di->di_printf("[r%d]", ((insn >> 16) & 0x0f));
break;
/* m - m register (bits 0-4) */
case 'm':
di->di_printf("r%d", ((insn >> 0) & 0x0f));
break;
/* a - address operand of ldr/str instruction */
case 'a':
disasm_insn_ldrstr(di, insn, loc);
break;
/* e - address operand of ldrh/strh instruction */
case 'e':
disasm_insn_ldrhstrh(di, insn, loc);
break;
/* l - register list for ldm/stm instruction */
case 'l':
disasm_print_reglist(di, insn);
break;
/* f - 1st fp operand (register) (bits 12-14) */
case 'f':
di->di_printf("f%d", (insn >> 12) & 7);
break;
/* g - 2nd fp operand (register) (bits 16-18) */
case 'g':
di->di_printf("f%d", (insn >> 16) & 7);
break;
/* h - 3rd fp operand (register/immediate) (bits 0-4) */
case 'h':
if (insn & (1 << 3))
di->di_printf("#%s", insn_fpaimm(insn));
else
di->di_printf("f%d", insn & 7);
break;
/* b - branch address */
case 'b':
branch = ((insn << 2) & 0x03ffffff);
if (branch & 0x02000000)
branch |= 0xfc000000;
di->di_printaddr(loc + 8 + branch);
break;
/* t - blx address */
case 't':
branch = ((insn << 2) & 0x03ffffff) |
(insn >> 23 & 0x00000002);
if (branch & 0x02000000)
branch |= 0xfc000000;
di->di_printaddr(loc + 8 + branch);
break;
/* X - block transfer type */
case 'X':
di->di_printf("%s", insn_blktrans(insn));
break;
/* Y - block transfer type (r13 base) */
case 'Y':
di->di_printf("%s", insn_stkblktrans(insn));
break;
/* c - comment field bits(0-23) */
case 'c':
di->di_printf("0x%08x", (insn & 0x00ffffff));
break;
/* k - breakpoint comment (bits 0-3, 8-19) */
case 'k':
di->di_printf("0x%04x",
(insn & 0x000fff00) >> 4 | (insn & 0x0000000f));
break;
/* p - saved or current status register */
case 'p':
if (insn & 0x00400000)
di->di_printf("spsr");
else
di->di_printf("cpsr");
break;
/* F - PSR transfer fields */
case 'F':
di->di_printf("_");
if (insn & (1 << 16))
di->di_printf("c");
if (insn & (1 << 17))
di->di_printf("x");
if (insn & (1 << 18))
di->di_printf("s");
if (insn & (1 << 19))
di->di_printf("f");
break;
/* B - byte transfer flag */
case 'B':
if (insn & 0x00400000)
di->di_printf("b");
break;
/* L - co-processor transfer size */
case 'L':
if (insn & (1 << 22))
di->di_printf("l");
break;
/* S - set status flag */
case 'S':
if (insn & 0x00100000)
di->di_printf("s");
break;
/* P - fp precision */
case 'P':
di->di_printf("%s", insn_fpaprec(insn));
break;
/* Q - fp precision (for ldf/stf) */
case 'Q':
break;
/* R - fp rounding */
case 'R':
di->di_printf("%s", insn_fparnd(insn));
break;
/* W - writeback flag */
case 'W':
if (insn & (1 << 21))
di->di_printf("!");
break;
/* # - co-processor number */
case '#':
di->di_printf("p%d", (insn >> 8) & 0x0f);
break;
/* v - co-processor data transfer registers+addressing mode */
case 'v':
disasm_insn_ldcstc(di, insn, loc);
break;
/* x - instruction in hex */
case 'x':
di->di_printf("0x%08x", insn);
break;
/* y - co-processor data processing registers */
case 'y':
di->di_printf("%d, ", (insn >> 20) & 0x0f);
di->di_printf("c%d, c%d, c%d", (insn >> 12) & 0x0f,
(insn >> 16) & 0x0f, insn & 0x0f);
di->di_printf(", %d", (insn >> 5) & 0x07);
break;
/* z - co-processor register transfer registers */
case 'z':
di->di_printf("%d, ", (insn >> 21) & 0x07);
di->di_printf("r%d, c%d, c%d, %d",
(insn >> 12) & 0x0f, (insn >> 16) & 0x0f,
insn & 0x0f, (insn >> 5) & 0x07);
/* if (((insn >> 5) & 0x07) != 0)
di->di_printf(", %d", (insn >> 5) & 0x07);*/
break;
default:
di->di_printf("[%c - unknown]", *f_ptr);
break;
}
if (*(f_ptr+1) >= 'A' && *(f_ptr+1) <= 'Z')
++f_ptr;
else if (*(++f_ptr)) {
++fmt;
if (fmt == 1)
di->di_printf("\t");
else
di->di_printf(", ");
}
};
di->di_printf("\n");
return(loc + INSN_SIZE);
}
static void
disasm_register_shift(const disasm_interface_t *di, u_int insn)
{
di->di_printf("r%d", (insn & 0x0f));
if ((insn & 0x00000ff0) == 0)
;
else if ((insn & 0x00000ff0) == 0x00000060)
di->di_printf(", rrx");
else {
if (insn & 0x10)
di->di_printf(", %s r%d", op2_shift(insn),
(insn >> 8) & 0x0f);
else
di->di_printf(", %s #%d", op2_shift(insn),
(insn >> 7) & 0x1f);
}
}
static void
disasm_print_reglist(const disasm_interface_t *di, u_int insn)
{
int loop;
int start;
int comma;
di->di_printf("{");
start = -1;
comma = 0;
for (loop = 0; loop < 17; ++loop) {
if (start != -1) {
if (loop == 16 || !(insn & (1 << loop))) {
if (comma)
di->di_printf(", ");
else
comma = 1;
if (start == loop - 1)
di->di_printf("r%d", start);
else
di->di_printf("r%d-r%d", start, loop - 1);
start = -1;
}
} else {
if (insn & (1 << loop))
start = loop;
}
}
di->di_printf("}");
if (insn & (1 << 22))
di->di_printf("^");
}
static void
disasm_insn_ldrstr(const disasm_interface_t *di, u_int insn, u_int loc)
{
int offset;
offset = insn & 0xfff;
if ((insn & 0x032f0000) == 0x010f0000) {
/* rA = pc, immediate index */
if (insn & 0x00800000)
loc += offset;
else
loc -= offset;
di->di_printaddr(loc + 8);
} else {
di->di_printf("[r%d", (insn >> 16) & 0x0f);
if ((insn & 0x03000fff) != 0x01000000) {
di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]");
if (!(insn & 0x00800000))
di->di_printf("-");
if (insn & (1 << 25))
disasm_register_shift(di, insn);
else
di->di_printf("#0x%03x", offset);
}
if (insn & (1 << 24))
di->di_printf("]");
}
}
static void
disasm_insn_ldrhstrh(const disasm_interface_t *di, u_int insn, u_int loc)
{
int offset;
offset = ((insn & 0xf00) >> 4) | (insn & 0xf);
if ((insn & 0x004f0000) == 0x004f0000) {
/* rA = pc, immediate index */
if (insn & 0x00800000)
loc += offset;
else
loc -= offset;
di->di_printaddr(loc + 8);
} else {
di->di_printf("[r%d", (insn >> 16) & 0x0f);
if ((insn & 0x01400f0f) != 0x01400000) {
di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]");
if (!(insn & 0x00800000))
di->di_printf("-");
if (insn & (1 << 22))
di->di_printf("#0x%02x", offset);
else
di->di_printf("r%d", (insn & 0x0f));
}
if (insn & (1 << 24))
di->di_printf("]");
}
}
static void
disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn, u_int loc)
{
if (((insn >> 8) & 0xf) == 1)
di->di_printf("f%d, ", (insn >> 12) & 0x07);
else
di->di_printf("c%d, ", (insn >> 12) & 0x0f);
di->di_printf("[r%d", (insn >> 16) & 0x0f);
di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]");
if (!(insn & (1 << 23)))
di->di_printf("-");
di->di_printf("#0x%03x", (insn & 0xff) << 2);
if (insn & (1 << 24))
di->di_printf("]");
if (insn & (1 << 21))
di->di_printf("!");
}
static u_int
disassemble_readword(u_int address)
{
return(*((u_int *)address));
}
static void
disassemble_printaddr(u_int address)
{
printf("0x%08x", address);
}
static const disasm_interface_t disassemble_di = {
disassemble_readword, disassemble_printaddr, db_printf
};
void
disassemble(u_int address)
{
(void)disasm(&disassemble_di, address, 0);
}
/* End of disassem.c */

View File

@ -0,0 +1,45 @@
/*-
* Copyright (c) 2004 Olivier Houchard
* All rights reserved.
*
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The names of the authors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/cons.h>
#include <sys/kernel.h>
#include <sys/kerneldump.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/md_var.h>
void
dumpsys(struct dumperinfo *di)
{
}

213
sys/arm/arm/elf_machdep.c Normal file
View File

@ -0,0 +1,213 @@
/*-
* Copyright 1996-1998 John D. Polstra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/linker.h>
#include <sys/sysent.h>
#include <sys/imgact_elf.h>
#include <sys/syscall.h>
#include <sys/signalvar.h>
#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_param.h>
#include <machine/elf.h>
#include <machine/md_var.h>
struct sysentvec elf32_freebsd_sysvec = {
SYS_MAXSYSCALL,
sysent,
0,
0,
NULL,
0,
NULL,
NULL,
__elfN(freebsd_fixup),
sendsig,
NULL,
NULL,
NULL,
"FreeBSD ELF32",
__elfN(coredump),
NULL,
MINSIGSTKSZ,
PAGE_SIZE,
VM_MIN_ADDRESS,
VM_MAXUSER_ADDRESS,
USRSTACK,
PS_STRINGS,
VM_PROT_ALL,
exec_copyout_strings,
exec_setregs,
NULL
};
static Elf32_Brandinfo freebsd_brand_info = {
ELFOSABI_FREEBSD,
EM_ARM,
"FreeBSD",
NULL,
"/libexec/ld-elf.so.1",
&elf32_freebsd_sysvec,
NULL,
};
SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_info);
static Elf32_Brandinfo freebsd_brand_oinfo = {
ELFOSABI_FREEBSD,
EM_ARM,
"FreeBSD",
NULL,
"/usr/libexec/ld-elf.so.1",
&elf32_freebsd_sysvec,
NULL,
};
SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_oinfo);
/* Process one elf relocation with addend. */
static int
elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)
{
Elf_Addr relocbase = (Elf_Addr) lf->address;
Elf_Addr *where;
Elf_Addr addr;
Elf_Addr addend;
Elf_Word rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
switch (type) {
case ELF_RELOC_REL:
rel = (const Elf_Rel *)data;
where = (Elf_Addr *) (relocbase + rel->r_offset);
addend = *where;
rtype = ELF_R_TYPE(rel->r_info);
symidx = ELF_R_SYM(rel->r_info);
break;
case ELF_RELOC_RELA:
rela = (const Elf_Rela *)data;
where = (Elf_Addr *) (relocbase + rela->r_offset);
addend = rela->r_addend;
rtype = ELF_R_TYPE(rela->r_info);
symidx = ELF_R_SYM(rela->r_info);
break;
default:
panic("unknown reloc type %d\n", type);
}
if (local) {
if (rtype == R_ARM_RELATIVE) { /* A + B */
addr = relocbase + addend;
if (*where != addr)
*where = addr;
}
return (0);
}
switch (rtype) {
case R_ARM_NONE: /* none */
break;
case R_ARM_PC24: /* S + A - P */
addr = elf_lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend - (Elf_Addr)where;
if (*where != addr)
*where = addr;
break;
case R_ARM_COPY: /* none */
/*
* There shouldn't be copy relocations in kernel
* objects.
*/
printf("kldload: unexpected R_COPY relocation\n");
return -1;
break;
case R_ARM_GLOB_DAT: /* S */
addr = elf_lookup(lf, symidx, 1);
if (addr == 0)
return -1;
if (*where != addr)
*where = addr;
break;
case R_ARM_RELATIVE:
break;
default:
printf("kldload: unexpected relocation type %d\n",
rtype);
return -1;
}
return(0);
}
int
elf_reloc(linker_file_t lf, const void *data, int type)
{
return (elf_reloc_internal(lf, data, type, 0));
}
int
elf_reloc_local(linker_file_t lf, const void *data, int type)
{
return (elf_reloc_internal(lf, data, type, 1));
}
int
elf_cpu_load_file(linker_file_t lf __unused)
{
return (0);
}
int
elf_cpu_unload_file(linker_file_t lf __unused)
{
return (0);
}

392
sys/arm/arm/exception.S Normal file
View File

@ -0,0 +1,392 @@
/* $NetBSD: exception.S,v 1.13 2003/10/31 16:30:15 scw Exp $ */
/*
* Copyright (c) 1994-1997 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* exception.S
*
* Low level handlers for exception vectors
*
* Created : 24/09/94
*
* Based on kate/display/abort.s
*
*/
#include "assym.s"
#include <machine/asm.h>
#include <machine/armreg.h>
#include <machine/asmacros.h>
__FBSDID("$FreeBSD$");
.text
.align 0
AST_ALIGNMENT_FAULT_LOCALS
/*
* reset_entry:
*
* Handler for Reset exception.
*/
ASENTRY_NP(reset_entry)
adr r0, Lreset_panicmsg
adr r1, Lfile
mov r2, #__LINE__
bl _C_LABEL(__panic)
/* NOTREACHED */
Lreset_panicmsg:
.asciz "Reset vector called, LR = 0x%08x"
Lfile:
.asciz __FILE__
.balign 4
/*
* swi_entry
*
* Handler for the Software Interrupt exception.
*/
ASENTRY_NP(swi_entry)
PUSHFRAME
ENABLE_ALIGNMENT_FAULTS
mov r0, sp /* Pass the frame to any function */
bl _C_LABEL(swi_handler) /* It's a SWI ! */
DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
PULLFRAME
movs pc, lr /* Exit */
/*
* prefetch_abort_entry:
*
* Handler for the Prefetch Abort exception.
*/
ASENTRY_NP(prefetch_abort_entry)
#ifdef __XSCALE__
nop /* Make absolutely sure any pending */
nop /* imprecise aborts have occurred. */
#endif
sub lr, lr, #0x00000004 /* Adjust the lr */
PUSHFRAMEINSVC
ENABLE_ALIGNMENT_FAULTS
ldr r1, Lprefetch_abort_handler_address
adr lr, exception_exit
mov r0, sp /* pass the stack pointer as r0 */
ldr pc, [r1]
Lprefetch_abort_handler_address:
.word _C_LABEL(prefetch_abort_handler_address)
.data
.global _C_LABEL(prefetch_abort_handler_address)
_C_LABEL(prefetch_abort_handler_address):
.word abortprefetch
.text
abortprefetch:
adr r0, abortprefetchmsg
adr r1, filee
mov r2, #__LINE__
b _C_LABEL(__panic)
filee:
.asciz __FILE__
abortprefetchmsg:
.asciz "abortprefetch"
.align 0
/*
* data_abort_entry:
*
* Handler for the Data Abort exception.
*/
ASENTRY_NP(data_abort_entry)
#ifdef __XSCALE__
nop /* Make absolutely sure any pending */
nop /* imprecise aborts have occurred. */
#endif
sub lr, lr, #0x00000008 /* Adjust the lr */
PUSHFRAMEINSVC /* Push trap frame and switch */
/* to SVC32 mode */
ENABLE_ALIGNMENT_FAULTS
ldr r1, Ldata_abort_handler_address
adr lr, exception_exit
mov r0, sp /* pass the stack pointer as r0 */
ldr pc, [r1]
Ldata_abort_handler_address:
.word _C_LABEL(data_abort_handler_address)
.data
.global _C_LABEL(data_abort_handler_address)
_C_LABEL(data_abort_handler_address):
.word abortdata
.text
abortdata:
adr r0, abortdatamsg
adr r1, file
mov r2, #__LINE__
b _C_LABEL(__panic)
abortdatamsg:
.asciz "abortdata"
file:
.asciz __FILE__
.align 0
/*
* address_exception_entry:
*
* Handler for the Address Exception exception.
*
* NOTE: This exception isn't really used on arm32. We
* print a warning message to the console and then treat
* it like a Data Abort.
*/
ASENTRY_NP(address_exception_entry)
mrs r1, cpsr_all
mrs r2, spsr_all
mov r3, lr
adr r0, Laddress_exception_msg
bl _C_LABEL(printf) /* XXX CLOBBERS LR!! */
b data_abort_entry
Laddress_exception_msg:
.asciz "Address Exception CPSR=0x%08x SPSR=0x%08x LR=0x%08x\n"
.balign 4
/*
* General exception exit handler
* (Placed here to be within range of all the references to it)
*
* It exits straight away if not returning to USR mode.
* This loops around delivering any pending ASTs.
* Interrupts are disabled at suitable points to avoid ASTs
* being posted between testing and exit to user mode.
*
* This function uses PULLFRAMEFROMSVCANDEXIT and
* DO_AST_AND_RESTORE_ALIGNMENT_FAULTS thus should
* only be called if the exception handler used PUSHFRAMEINSVC
* followed by ENABLE_ALIGNMENT_FAULTS.
*/
exception_exit:
DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
PULLFRAMEFROMSVCANDEXIT
/*
* undefined_entry:
*
* Handler for the Undefined Instruction exception.
*
* We indirect the undefined vector via the handler address
* in the data area. Entry to the undefined handler must
* look like direct entry from the vector.
*/
ASENTRY_NP(undefined_entry)
#ifdef IPKDB
/*
* IPKDB must be hooked in at the earliest possible entry point.
*
*/
/*
* Make room for all registers saving real r0-r7 and r15.
* The remaining registers are updated later.
*/
stmfd sp!, {r0,r1} /* psr & spsr */
stmfd sp!, {lr} /* pc */
stmfd sp!, {r0-r14} /* r0-r7, r8-r14 */
/*
* Get previous psr.
*/
mrs r7, cpsr_all
mrs r0, spsr_all
str r0, [sp, #(16*4)]
/*
* Test for user mode.
*/
tst r0, #0xf
bne .Lprenotuser_push
add r1, sp, #(8*4)
stmia r1,{r8-r14}^ /* store user mode r8-r14*/
b .Lgoipkdb
/*
* Switch to previous mode to get r8-r13.
*/
.Lprenotuser_push:
orr r0, r0, #(I32_bit) /* disable interrupts */
msr cpsr_all, r0
mov r1, r8
mov r2, r9
mov r3, r10
mov r4, r11
mov r5, r12
mov r6, r13
msr cpsr_all, r7 /* back to undefined mode */
add r8, sp, #(8*4)
stmia r8, {r1-r6} /* r8-r13 */
/*
* Now back to previous mode to get r14 and spsr.
*/
msr cpsr_all, r0
mov r1, r14
mrs r2, spsr
msr cpsr_all, r7 /* back to undefined mode */
str r1, [sp, #(14*4)] /* r14 */
str r2, [sp, #(17*4)] /* spsr */
/*
* Now to IPKDB.
*/
.Lgoipkdb:
mov r0, sp
bl _C_LABEL(ipkdb_trap_glue)
ldr r1, .Lipkdb_trap_return
str r0,[r1]
/*
* Have to load all registers from the stack.
*
* Start with spsr and pc.
*/
ldr r0, [sp, #(16*4)] /* spsr */
ldr r1, [sp, #(15*4)] /* r15 */
msr spsr_all, r0
mov r14, r1
/*
* Test for user mode.
*/
tst r0, #0xf
bne .Lprenotuser_pull
add r1, sp, #(8*4)
ldmia r1, {r8-r14}^ /* load user mode r8-r14 */
b .Lpull_r0r7
.Lprenotuser_pull:
/*
* Now previous mode spsr and r14.
*/
ldr r1, [sp, #(17*4)] /* spsr */
ldr r2, [sp, #(14*4)] /* r14 */
orr r0, r0, #(I32_bit)
msr cpsr_all, r0 /* switch to previous mode */
msr spsr_all, r1
mov r14, r2
msr cpsr_all, r7 /* back to undefined mode */
/*
* Now r8-r13.
*/
add r8, sp, #(8*4)
ldmia r8, {r1-r6} /* r8-r13 */
msr cpsr_all, r0
mov r8, r1
mov r9, r2
mov r10, r3
mov r11, r4
mov r12, r5
mov r13, r6
msr cpsr_all, r7
.Lpull_r0r7:
/*
* Now the rest of the registers.
*/
ldr r1,Lipkdb_trap_return
ldr r0,[r1]
tst r0,r0
ldmfd sp!, {r0-r7} /* r0-r7 */
add sp, sp, #(10*4) /* adjust sp */
/*
* Did IPKDB handle it?
*/
movnes pc, lr /* return */
#endif
stmfd sp!, {r0, r1}
ldr r0, Lundefined_handler_indirection
ldr r1, [sp], #0x0004
str r1, [r0, #0x0000]
ldr r1, [sp], #0x0004
str r1, [r0, #0x0004]
ldmia r0, {r0, r1, pc}
#ifdef IPKDB
Lipkdb_trap_return:
.word Lipkdb_trap_return_data
#endif
Lundefined_handler_indirection:
.word Lundefined_handler_indirection_data
/*
* assembly bounce code for calling the kernel
* undefined instruction handler. This uses
* a standard trap frame and is called in SVC mode.
*/
ENTRY_NP(undefinedinstruction_bounce)
PUSHFRAMEINSVC
ENABLE_ALIGNMENT_FAULTS
mov r0, sp
adr lr, exception_exit
b _C_LABEL(undefinedinstruction)
.data
.align 0
#ifdef IPKDB
Lipkdb_trap_return_data:
.word 0
#endif
/*
* Indirection data
* 2 words use for preserving r0 and r1
* 3rd word contains the undefined handler address.
*/
Lundefined_handler_indirection_data:
.word 0
.word 0
.global _C_LABEL(undefined_handler_address)
_C_LABEL(undefined_handler_address):
.word _C_LABEL(undefinedinstruction_bounce)

169
sys/arm/arm/fiq.c Normal file
View File

@ -0,0 +1,169 @@
/* $NetBSD: fiq.c,v 1.5 2002/04/03 23:33:27 thorpej Exp $ */
/*
* Copyright (c) 2001, 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <machine/cpufunc.h>
#include <machine/fiq.h>
#include <vm/vm.h>
#include <machine/pcb.h>
#include <vm/pmap.h>
TAILQ_HEAD(, fiqhandler) fiqhandler_stack =
TAILQ_HEAD_INITIALIZER(fiqhandler_stack);
extern char fiqvector[];
extern char fiq_nullhandler[], fiq_nullhandler_end[];
#define IRQ_BIT I32_bit
#define FIQ_BIT F32_bit
/*
* fiq_installhandler:
*
* Actually install the FIQ handler down at the FIQ vector.
*
* Note: If the FIQ is invoked via an extra layer of
* indirection, the actual FIQ code store lives in the
* data segment, so there is no need to manipulate
* the vector page's protection.
*/
static void
fiq_installhandler(void *func, size_t size)
{
#if !defined(__ARM_FIQ_INDIRECT)
vector_page_setprot(VM_PROT_READ|VM_PROT_WRITE);
#endif
memcpy(fiqvector, func, size);
#if !defined(__ARM_FIQ_INDIRECT)
vector_page_setprot(VM_PROT_READ);
cpu_icache_sync_range((vm_offset_t) fiqvector, size);
#endif
}
/*
* fiq_claim:
*
* Claim the FIQ vector.
*/
int
fiq_claim(struct fiqhandler *fh)
{
struct fiqhandler *ofh;
u_int oldirqstate;
int error = 0;
if (fh->fh_size > 0x100)
return (EFBIG);
oldirqstate = disable_interrupts(FIQ_BIT);
if ((ofh = TAILQ_FIRST(&fiqhandler_stack)) != NULL) {
if ((ofh->fh_flags & FH_CANPUSH) == 0) {
error = EBUSY;
goto out;
}
/* Save the previous FIQ handler's registers. */
if (ofh->fh_regs != NULL)
fiq_getregs(ofh->fh_regs);
}
/* Set FIQ mode registers to ours. */
if (fh->fh_regs != NULL)
fiq_setregs(fh->fh_regs);
TAILQ_INSERT_HEAD(&fiqhandler_stack, fh, fh_list);
/* Now copy the actual handler into place. */
fiq_installhandler(fh->fh_func, fh->fh_size);
/* Make sure FIQs are enabled when we return. */
oldirqstate &= ~FIQ_BIT;
out:
restore_interrupts(oldirqstate);
return (error);
}
/*
* fiq_release:
*
* Release the FIQ vector.
*/
void
fiq_release(struct fiqhandler *fh)
{
u_int oldirqstate;
struct fiqhandler *ofh;
oldirqstate = disable_interrupts(FIQ_BIT);
/*
* If we are the currently active FIQ handler, then we
* need to save our registers and pop the next one back
* into the vector.
*/
if (fh == TAILQ_FIRST(&fiqhandler_stack)) {
if (fh->fh_regs != NULL)
fiq_getregs(fh->fh_regs);
TAILQ_REMOVE(&fiqhandler_stack, fh, fh_list);
if ((ofh = TAILQ_FIRST(&fiqhandler_stack)) != NULL) {
if (ofh->fh_regs != NULL)
fiq_setregs(ofh->fh_regs);
fiq_installhandler(ofh->fh_func, ofh->fh_size);
}
} else
TAILQ_REMOVE(&fiqhandler_stack, fh, fh_list);
if (TAILQ_FIRST(&fiqhandler_stack) == NULL) {
/* Copy the NULL handler back down into the vector. */
fiq_installhandler(fiq_nullhandler,
(size_t)(fiq_nullhandler_end - fiq_nullhandler));
/* Make sure FIQs are disabled when we return. */
oldirqstate |= FIQ_BIT;
}
restore_interrupts(oldirqstate);
}

101
sys/arm/arm/fiq_subr.S Normal file
View File

@ -0,0 +1,101 @@
/* $NetBSD: fiq_subr.S,v 1.3 2002/04/12 18:50:31 thorpej Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/armreg.h>
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* MODE_CHANGE_NOP should be inserted between a mode change and a
* banked register (R8--R15) access.
*/
#if defined(CPU_ARM2) || defined(CPU_ARM250)
#define MODE_CHANGE_NOP mov r0, r0
#else
#define MODE_CHANGE_NOP /* Data sheet says ARM3 doesn't need it */
#endif
#define SWITCH_TO_FIQ_MODE \
mrs r2, cpsr_all ; \
mov r3, r2 ; \
bic r2, r2, #(PSR_MODE) ; \
orr r2, r2, #(PSR_FIQ32_MODE) ; \
msr cpsr_all, r2
#define BACK_TO_SVC_MODE \
msr cpsr_all, r3
/*
* fiq_getregs:
*
* Fetch the FIQ mode banked registers into the fiqhandler
* structure.
*/
ENTRY(fiq_getregs)
SWITCH_TO_FIQ_MODE
stmia r0, {r8-r13}
BACK_TO_SVC_MODE
mov pc, lr
/*
* fiq_setregs:
*
* Load the FIQ mode banked registers from the fiqhandler
* structure.
*/
ENTRY(fiq_setregs)
SWITCH_TO_FIQ_MODE
ldmia r0, {r8-r13}
BACK_TO_SVC_MODE
mov pc, lr
/*
* fiq_nullhandler:
*
* Null handler copied down to the FIQ vector when the last
* FIQ handler is removed.
*/
.global _C_LABEL(fiq_nullhandler), _C_LABEL(fiq_nullhandler_end)
_C_LABEL(fiq_nullhandler):
subs pc, lr, #4
_C_LABEL(fiq_nullhandler_end):

403
sys/arm/arm/fusu.S Normal file
View File

@ -0,0 +1,403 @@
/* $NetBSD: fusu.S,v 1.10 2003/12/01 13:34:44 rearnsha Exp $ */
/*
* Copyright (c) 1996-1998 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <machine/asm.h>
#include <machine/asmacros.h>
#include <machine/armreg.h>
#include "assym.s"
__FBSDID("$FreeBSD$");
#ifdef MULTIPROCESSOR
.Lcpu_info:
.word _C_LABEL(cpu_info)
#else
.Lcurpcb:
.word _C_LABEL(__pcpu) + PC_CURPCB
#endif
/*
* fuword(caddr_t uaddr);
* Fetch an int from the user's address space.
*/
ENTRY(fuword)
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
#ifdef DIAGNOSTIC
teq r2, #0x00000000
beq .Lfusupcbfault
#endif
adr r1, .Lfusufault
str r1, [r2, #PCB_ONFAULT]
ldrt r3, [r0]
mov r1, #0x00000000
str r1, [r2, #PCB_ONFAULT]
mov r0, r3
mov pc, lr
ENTRY(fuword32)
bl _C_LABEL(fuword)
/*
* fusword(caddr_t uaddr);
* Fetch a short from the user's address space.
*/
ENTRY(fusword)
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
#ifdef DIAGNOSTIC
teq r2, #0x00000000
beq .Lfusupcbfault
#endif
adr r1, .Lfusufault
str r1, [r2, #PCB_ONFAULT]
ldrbt r3, [r0], #1
ldrbt ip, [r0]
#ifdef __ARMEB__
orr r0, ip, r3, asl #8
#else
orr r0, r3, ip, asl #8
#endif
mov r1, #0x00000000
str r1, [r2, #PCB_ONFAULT]
mov pc, lr
/*
* fuswintr(caddr_t uaddr);
* Fetch a short from the user's address space. Can be called during an
* interrupt.
*/
ENTRY(fuswintr)
ldr r2, Lblock_userspace_access
ldr r2, [r2]
teq r2, #0
mvnne r0, #0x00000000
movne pc, lr
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
#ifdef DIAGNOSTIC
teq r2, #0x00000000
beq .Lfusupcbfault
#endif
adr r1, _C_LABEL(fusubailout)
str r1, [r2, #PCB_ONFAULT]
ldrbt r3, [r0], #1
ldrbt ip, [r0]
#ifdef __ARMEB__
orr r0, ip, r3, asl #8
#else
orr r0, r3, ip, asl #8
#endif
mov r1, #0x00000000
str r1, [r2, #PCB_ONFAULT]
mov pc, lr
Lblock_userspace_access:
.word _C_LABEL(block_userspace_access)
.data
.align 0
.global _C_LABEL(block_userspace_access)
_C_LABEL(block_userspace_access):
.word 0
.text
/*
* fubyte(caddr_t uaddr);
* Fetch a byte from the user's address space.
*/
ENTRY(fubyte)
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
#ifdef DIAGNOSTIC
teq r2, #0x00000000
beq .Lfusupcbfault
#endif
adr r1, .Lfusufault
str r1, [r2, #PCB_ONFAULT]
ldrbt r3, [r0]
mov r1, #0x00000000
str r1, [r2, #PCB_ONFAULT]
mov r0, r3
mov pc, lr
/*
* Handle faults from [fs]u*(). Clean up and return -1.
*/
.Lfusufault:
mov r0, #0x00000000
str r0, [r2, #PCB_ONFAULT]
mvn r0, #0x00000000
mov pc, lr
/*
* Handle faults from [fs]u*(). Clean up and return -1. This differs from
* fusufault() in that trap() will recognise it and return immediately rather
* than trying to page fault.
*/
/* label must be global as fault.c references it */
.global _C_LABEL(fusubailout)
_C_LABEL(fusubailout):
mov r0, #0x00000000
str r0, [r2, #PCB_ONFAULT]
mvn r0, #0x00000000
mov pc, lr
#ifdef DIAGNOSTIC
/*
* Handle earlier faults from [fs]u*(), due to no pcb
*/
.Lfusupcbfault:
mov r1, r0
adr r0, fusupcbfaulttext
b _C_LABEL(panic)
fusupcbfaulttext:
.asciz "Yikes - no valid PCB during fusuxxx() addr=%08x\n"
.align 0
#endif
/*
* suword(caddr_t uaddr, int x);
* Store an int in the user's address space.
*/
ENTRY(suword)
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0, r1, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0, r1, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
#ifdef DIAGNOSTIC
teq r2, #0x00000000
beq .Lfusupcbfault
#endif
adr r3, .Lfusufault
str r3, [r2, #PCB_ONFAULT]
strt r1, [r0]
mov r0, #0x00000000
str r0, [r2, #PCB_ONFAULT]
mov pc, lr
ENTRY(suword32)
adr pc, _C_LABEL(suword)
/*
* suswintr(caddr_t uaddr, short x);
* Store a short in the user's address space. Can be called during an
* interrupt.
*/
ENTRY(suswintr)
ldr r2, Lblock_userspace_access
ldr r2, [r2]
teq r2, #0
mvnne r0, #0x00000000
movne pc, lr
#ifdef MULTIPROCESSOR
stmfd sp!, {r0, r1, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0, r1, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
#ifdef DIAGNOSTIC
teq r2, #0x00000000
beq .Lfusupcbfault
#endif
adr r3, _C_LABEL(fusubailout)
str r3, [r2, #PCB_ONFAULT]
#ifdef __ARMEB__
mov ip, r1, lsr #8
strbt ip, [r0], #1
#else
strbt r1, [r0], #1
mov r1, r1, lsr #8
#endif
strbt r1, [r0]
mov r0, #0x00000000
str r0, [r2, #PCB_ONFAULT]
mov pc, lr
/*
* susword(caddr_t uaddr, short x);
* Store a short in the user's address space.
*/
ENTRY(susword)
#ifdef MULTIPROCESSOR
stmfd sp!, {r0, r1, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0, r1, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
#ifdef DIAGNOSTIC
teq r2, #0x00000000
beq .Lfusupcbfault
#endif
adr r3, .Lfusufault
str r3, [r2, #PCB_ONFAULT]
#ifdef __ARMEB__
mov ip, r1, lsr #8
strbt ip, [r0], #1
#else
strbt r1, [r0], #1
mov r1, r1, lsr #8
#endif
strbt r1, [r0]
mov r0, #0x00000000
str r0, [r2, #PCB_ONFAULT]
mov pc, lr
/*
* subyte(caddr_t uaddr, char x);
* Store a byte in the user's address space.
*/
ENTRY(subyte)
#ifdef MULTIPROCESSOR
stmfd sp!, {r0, r1, r14}
bl _C_LABEL(cpu_number)
ldr r2, .Lcpu_info
ldr r2, [r2, r0, lsl #2]
ldr r2, [r2, #CI_CURPCB]
ldmfd sp!, {r0, r1, r14}
#else
ldr r2, .Lcurpcb
ldr r2, [r2]
#endif
#ifdef DIAGNOSTIC
teq r2, #0x00000000
beq .Lfusupcbfault
#endif
adr r3, .Lfusufault
str r3, [r2, #PCB_ONFAULT]
strbt r1, [r0]
mov r0, #0x00000000
str r0, [r2, #PCB_ONFAULT]
mov pc, lr

112
sys/arm/arm/genassym.c Normal file
View File

@ -0,0 +1,112 @@
/*-
* Copyright (c) 2004 Olivier Houchard
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/assym.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/mbuf.h>
#include <sys/vmmeter.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/vmparam.h>
#include <machine/armreg.h>
#include <machine/pcb.h>
#include <machine/cpu.h>
#include <machine/proc.h>
#include <machine/cpufunc.h>
#include <machine/pte.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/ip_var.h>
ASSYM(KERNBASE, KERNBASE);
ASSYM(PCB_NOALIGNFLT, PCB_NOALIGNFLT);
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
ASSYM(PCB_DACR, offsetof(struct pcb, pcb_dacr));
ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
ASSYM(PCB_CSTATE, offsetof(struct pcb, pcb_cstate));
ASSYM(PCB_UND_SP, offsetof(struct pcb, un_32.pcb32_und_sp));
ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir));
ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec));
ASSYM(PCB_PL1VEC, offsetof(struct pcb, pcb_pl1vec));
ASSYM(PCB_R8, offsetof(struct pcb, un_32.pcb32_r8));
ASSYM(PCB_R9, offsetof(struct pcb, un_32.pcb32_r9));
ASSYM(PCB_R10, offsetof(struct pcb, un_32.pcb32_r10));
ASSYM(PCB_R11, offsetof(struct pcb, un_32.pcb32_r11));
ASSYM(PCB_R12, offsetof(struct pcb, un_32.pcb32_r12));
ASSYM(PCB_PC, offsetof(struct pcb, un_32.pcb32_pc));
ASSYM(PCB_SP, offsetof(struct pcb, un_32.pcb32_sp));
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
ASSYM(M_LEN, offsetof(struct mbuf, m_len));
ASSYM(M_DATA, offsetof(struct mbuf, m_data));
ASSYM(M_NEXT, offsetof(struct mbuf, m_next));
ASSYM(IP_SRC, offsetof(struct ip, ip_src));
ASSYM(IP_DST, offsetof(struct ip, ip_dst));
ASSYM(CF_SETTTB, offsetof(struct cpu_functions, cf_setttb));
ASSYM(CF_CONTROL, offsetof(struct cpu_functions, cf_control));
ASSYM(CF_CONTEXT_SWITCH, offsetof(struct cpu_functions, cf_context_switch));
ASSYM(CF_DCACHE_WB_RANGE, offsetof(struct cpu_functions, cf_dcache_wb_range));
ASSYM(CF_IDCACHE_WBINV_ALL, offsetof(struct cpu_functions, cf_idcache_wbinv_all));
ASSYM(CF_TLB_FLUSHID_SE, offsetof(struct cpu_functions, cf_tlb_flushID_SE));
ASSYM(CS_ALL, offsetof(union pmap_cache_state, cs_all));
ASSYM(CS_CACHE_ID, offsetof(union pmap_cache_state, cs_cache_id));
ASSYM(CS_TLB_ID, offsetof(union pmap_cache_state, cs_tlb_id));
ASSYM(CS_CACHE_D, offsetof(union pmap_cache_state, cs_cache_d));
ASSYM(PMAP_CSTATE, offsetof(struct pmap, pm_cstate));
ASSYM(V_TRAP, offsetof(struct vmmeter, v_trap));
ASSYM(V_SOFT, offsetof(struct vmmeter, v_soft));
ASSYM(V_INTR, offsetof(struct vmmeter, v_intr));
ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
ASSYM(TF_R0, offsetof(struct trapframe, tf_r0));
ASSYM(TF_R1, offsetof(struct trapframe, tf_r1));
ASSYM(TF_PC, offsetof(struct trapframe, tf_pc));
ASSYM(P_UAREA, offsetof(struct proc, p_uarea));
ASSYM(P_PID, offsetof(struct proc, p_pid));
ASSYM(P_FLAG, offsetof(struct proc, p_flag));
ASSYM(PDESIZE, PDESIZE);
ASSYM(PMAP_DOMAIN_KERNEL, PMAP_DOMAIN_KERNEL);
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
ASSYM(USER_SIZE, sizeof(struct user));
ASSYM(P_TRACED, P_TRACED);
ASSYM(P_SIGEVENT, P_SIGEVENT);
ASSYM(P_PROFIL, P_PROFIL);
ASSYM(TRAPFRAMESIZE, sizeof(struct trapframe));

366
sys/arm/arm/identcpu.c Normal file
View File

@ -0,0 +1,366 @@
/* $NetBSD: cpu.c,v 1.55 2004/02/13 11:36:10 wiz Exp $ */
/*
* Copyright (c) 1995 Mark Brinicombe.
* Copyright (c) 1995 Brini.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* cpu.c
*
* Probing and configuration for the master CPU
*
* Created : 10/10/95
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/time.h>
#include <sys/proc.h>
#include <sys/conf.h>
#include <machine/cpu.h>
#include <machine/cpuconf.h>
char machine[] = "arm";
enum cpu_class {
CPU_CLASS_NONE,
CPU_CLASS_ARM2,
CPU_CLASS_ARM2AS,
CPU_CLASS_ARM3,
CPU_CLASS_ARM6,
CPU_CLASS_ARM7,
CPU_CLASS_ARM7TDMI,
CPU_CLASS_ARM8,
CPU_CLASS_ARM9TDMI,
CPU_CLASS_ARM9ES,
CPU_CLASS_ARM10E,
CPU_CLASS_SA1,
CPU_CLASS_XSCALE
};
static const char * const generic_steppings[16] = {
"rev 0", "rev 1", "rev 2", "rev 3",
"rev 4", "rev 5", "rev 6", "rev 7",
"rev 8", "rev 9", "rev 10", "rev 11",
"rev 12", "rev 13", "rev 14", "rev 15",
};
static const char * const sa110_steppings[16] = {
"rev 0", "step J", "step K", "step S",
"step T", "rev 5", "rev 6", "rev 7",
"rev 8", "rev 9", "rev 10", "rev 11",
"rev 12", "rev 13", "rev 14", "rev 15",
};
static const char * const sa1100_steppings[16] = {
"rev 0", "step B", "step C", "rev 3",
"rev 4", "rev 5", "rev 6", "rev 7",
"step D", "step E", "rev 10" "step G",
"rev 12", "rev 13", "rev 14", "rev 15",
};
static const char * const sa1110_steppings[16] = {
"step A-0", "rev 1", "rev 2", "rev 3",
"step B-0", "step B-1", "step B-2", "step B-3",
"step B-4", "step B-5", "rev 10", "rev 11",
"rev 12", "rev 13", "rev 14", "rev 15",
};
static const char * const ixp12x0_steppings[16] = {
"(IXP1200 step A)", "(IXP1200 step B)",
"rev 2", "(IXP1200 step C)",
"(IXP1200 step D)", "(IXP1240/1250 step A)",
"(IXP1240 step B)", "(IXP1250 step B)",
"rev 8", "rev 9", "rev 10", "rev 11",
"rev 12", "rev 13", "rev 14", "rev 15",
};
static const char * const xscale_steppings[16] = {
"step A-0", "step A-1", "step B-0", "step C-0",
"step D-0", "rev 5", "rev 6", "rev 7",
"rev 8", "rev 9", "rev 10", "rev 11",
"rev 12", "rev 13", "rev 14", "rev 15",
};
static const char * const i80321_steppings[16] = {
"step A-0", "step B-0", "rev 2", "rev 3",
"rev 4", "rev 5", "rev 6", "rev 7",
"rev 8", "rev 9", "rev 10", "rev 11",
"rev 12", "rev 13", "rev 14", "rev 15",
};
static const char * const pxa2x0_steppings[16] = {
"step A-0", "step A-1", "step B-0", "step B-1",
"step B-2", "step C-0", "rev 6", "rev 7",
"rev 8", "rev 9", "rev 10", "rev 11",
"rev 12", "rev 13", "rev 14", "rev 15",
};
static const char * const ixp425_steppings[16] = {
"step 0", "rev 1", "rev 2", "rev 3",
"rev 4", "rev 5", "rev 6", "rev 7",
"rev 8", "rev 9", "rev 10", "rev 11",
"rev 12", "rev 13", "rev 14", "rev 15",
};
struct cpuidtab {
u_int32_t cpuid;
enum cpu_class cpu_class;
const char *cpu_name;
const char * const *cpu_steppings;
};
const struct cpuidtab cpuids[] = {
{ CPU_ID_ARM2, CPU_CLASS_ARM2, "ARM2",
generic_steppings },
{ CPU_ID_ARM250, CPU_CLASS_ARM2AS, "ARM250",
generic_steppings },
{ CPU_ID_ARM3, CPU_CLASS_ARM3, "ARM3",
generic_steppings },
{ CPU_ID_ARM600, CPU_CLASS_ARM6, "ARM600",
generic_steppings },
{ CPU_ID_ARM610, CPU_CLASS_ARM6, "ARM610",
generic_steppings },
{ CPU_ID_ARM620, CPU_CLASS_ARM6, "ARM620",
generic_steppings },
{ CPU_ID_ARM700, CPU_CLASS_ARM7, "ARM700",
generic_steppings },
{ CPU_ID_ARM710, CPU_CLASS_ARM7, "ARM710",
generic_steppings },
{ CPU_ID_ARM7500, CPU_CLASS_ARM7, "ARM7500",
generic_steppings },
{ CPU_ID_ARM710A, CPU_CLASS_ARM7, "ARM710a",
generic_steppings },
{ CPU_ID_ARM7500FE, CPU_CLASS_ARM7, "ARM7500FE",
generic_steppings },
{ CPU_ID_ARM710T, CPU_CLASS_ARM7TDMI, "ARM710T",
generic_steppings },
{ CPU_ID_ARM720T, CPU_CLASS_ARM7TDMI, "ARM720T",
generic_steppings },
{ CPU_ID_ARM740T8K, CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)",
generic_steppings },
{ CPU_ID_ARM740T4K, CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)",
generic_steppings },
{ CPU_ID_ARM810, CPU_CLASS_ARM8, "ARM810",
generic_steppings },
{ CPU_ID_ARM920T, CPU_CLASS_ARM9TDMI, "ARM920T",
generic_steppings },
{ CPU_ID_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T",
generic_steppings },
{ CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T",
generic_steppings },
{ CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S",
generic_steppings },
{ CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S",
generic_steppings },
{ CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S",
generic_steppings },
{ CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T",
generic_steppings },
{ CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E",
generic_steppings },
{ CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S",
generic_steppings },
{ CPU_ID_SA110, CPU_CLASS_SA1, "SA-110",
sa110_steppings },
{ CPU_ID_SA1100, CPU_CLASS_SA1, "SA-1100",
sa1100_steppings },
{ CPU_ID_SA1110, CPU_CLASS_SA1, "SA-1110",
sa1110_steppings },
{ CPU_ID_IXP1200, CPU_CLASS_SA1, "IXP1200",
ixp12x0_steppings },
{ CPU_ID_80200, CPU_CLASS_XSCALE, "i80200",
xscale_steppings },
{ CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz",
i80321_steppings },
{ CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz",
i80321_steppings },
{ CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz",
i80321_steppings },
{ CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz",
i80321_steppings },
{ CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250",
pxa2x0_steppings },
{ CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210",
pxa2x0_steppings },
{ CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250",
pxa2x0_steppings },
{ CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210",
pxa2x0_steppings },
{ CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA250",
pxa2x0_steppings },
{ CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210",
pxa2x0_steppings },
{ CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz",
ixp425_steppings },
{ CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz",
ixp425_steppings },
{ CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz",
ixp425_steppings },
{ 0, CPU_CLASS_NONE, NULL, NULL }
};
struct cpu_classtab {
const char *class_name;
const char *class_option;
};
const struct cpu_classtab cpu_classes[] = {
{ "unknown", NULL }, /* CPU_CLASS_NONE */
{ "ARM2", "CPU_ARM2" }, /* CPU_CLASS_ARM2 */
{ "ARM2as", "CPU_ARM250" }, /* CPU_CLASS_ARM2AS */
{ "ARM3", "CPU_ARM3" }, /* CPU_CLASS_ARM3 */
{ "ARM6", "CPU_ARM6" }, /* CPU_CLASS_ARM6 */
{ "ARM7", "CPU_ARM7" }, /* CPU_CLASS_ARM7 */
{ "ARM7TDMI", "CPU_ARM7TDMI" }, /* CPU_CLASS_ARM7TDMI */
{ "ARM8", "CPU_ARM8" }, /* CPU_CLASS_ARM8 */
{ "ARM9TDMI", NULL }, /* CPU_CLASS_ARM9TDMI */
{ "ARM9E-S", NULL }, /* CPU_CLASS_ARM9ES */
{ "ARM10E", "CPU_ARM10" }, /* CPU_CLASS_ARM10E */
{ "SA-1", "CPU_SA110" }, /* CPU_CLASS_SA1 */
{ "XScale", "CPU_XSCALE_..." }, /* CPU_CLASS_XSCALE */
};
/*
* Report the type of the specified arm processor. This uses the generic and
* arm specific information in the cpu structure to identify the processor.
* The remaining fields in the cpu structure are filled in appropriately.
*/
#if 0
static const char * const wtnames[] = {
"write-through",
"write-back",
"write-back",
"**unknown 3**",
"**unknown 4**",
"write-back-locking", /* XXX XScale-specific? */
"write-back-locking-A",
"write-back-locking-B",
"**unknown 8**",
"**unknown 9**",
"**unknown 10**",
"**unknown 11**",
"**unknown 12**",
"**unknown 13**",
"**unknown 14**",
"**unknown 15**",
};
#endif
extern int ctrl;
void
identify_arm_cpu(void)
{
u_int cpuid;
enum cpu_class cpu_class = CPU_CLASS_NONE;
int i;
cpuid = cpu_id();
if (cpuid == 0) {
printf("Processor failed probe - no CPU ID\n");
return;
}
for (i = 0; cpuids[i].cpuid != 0; i++)
if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
cpu_class = cpuids[i].cpu_class;
printf("%s %s (%s core)\n",
cpuids[i].cpu_name,
cpuids[i].cpu_steppings[cpuid &
CPU_ID_REVISION_MASK],
cpu_classes[cpu_class].class_name);
break;
}
if (cpuids[i].cpuid == 0)
printf("unknown CPU (ID = 0x%x)\n", cpuid);
switch (cpu_class) {
case CPU_CLASS_ARM6:
case CPU_CLASS_ARM7:
case CPU_CLASS_ARM7TDMI:
case CPU_CLASS_ARM8:
if ((ctrl & CPU_CONTROL_IDC_ENABLE) == 0)
printf(" IDC disabled");
else
printf(" IDC enabled");
break;
case CPU_CLASS_ARM9TDMI:
case CPU_CLASS_ARM10E:
case CPU_CLASS_SA1:
case CPU_CLASS_XSCALE:
if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0)
printf(" DC disabled");
else
printf(" DC enabled");
if ((ctrl & CPU_CONTROL_IC_ENABLE) == 0)
printf(" IC disabled");
else
printf(" IC enabled");
break;
default:
break;
}
if ((ctrl & CPU_CONTROL_WBUF_ENABLE) == 0)
printf(" WB disabled");
else
printf(" WB enabled");
if (ctrl & CPU_CONTROL_LABT_ENABLE)
printf(" LABT");
else
printf(" EABT");
if (ctrl & CPU_CONTROL_BPRD_ENABLE)
printf(" branch prediction enabled");
printf("\n");
}

250
sys/arm/arm/in_cksum.c Normal file
View File

@ -0,0 +1,250 @@
/* $NetBSD: in_cksum.c,v 1.7 1997/09/02 13:18:15 thorpej Exp $ */
/*
* Copyright (c) 1988, 1992, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1996
* Matt Thomas <matt@3am-software.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/systm.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <machine/in_cksum.h>
/*
* Checksum routine for Internet Protocol family headers
* (Portable Alpha version).
*
* This routine is very heavily used in the network
* code and should be modified for each CPU to be as fast as possible.
*/
#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
#define REDUCE32 \
{ \
q_util.q = sum; \
sum = q_util.s[0] + q_util.s[1] + q_util.s[2] + q_util.s[3]; \
}
#define REDUCE16 \
{ \
q_util.q = sum; \
l_util.l = q_util.s[0] + q_util.s[1] + q_util.s[2] + q_util.s[3]; \
sum = l_util.s[0] + l_util.s[1]; \
ADDCARRY(sum); \
}
static const u_int32_t in_masks[] = {
#if 0
/*0 bytes*/ /*1 byte*/ /*2 bytes*/ /*3 bytes*/
0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF, /* offset 0 */
0x00000000, 0x0000FF00, 0x00FFFF00, 0xFFFFFF00, /* offset 1 */
0x00000000, 0x00FF0000, 0xFFFF0000, 0xFFFF0000, /* offset 2 */
0x00000000, 0xFF000000, 0xFF000000, 0xFF000000, /* offset 3 */
#else
/*0 bytes*/ /*1 byte*/ /*2 bytes*/ /*3 bytes*/
0x00000000, 0xFF000000, 0xFFFF0000, 0xFFFFFF00, /* offset 0 */
0x00000000, 0x00FF0000, 0x00FFFF00, 0x00FFFFFF, /* offset 1 */
0x00000000, 0x0000FF00, 0x0000FFFF, 0x0000FFFF, /* offset 2 */
0x00000000, 0x000000FF, 0x000000FF, 0x000000FF, /* offset 3 */
#endif
};
union l_util {
u_int16_t s[2];
u_int32_t l;
};
union q_util {
u_int16_t s[4];
u_int32_t l[2];
u_int64_t q;
};
static u_int64_t
in_cksumdata(const void *buf, int len)
{
const u_int32_t *lw = (const u_int32_t *) buf;
u_int64_t sum = 0;
u_int64_t prefilled;
int offset;
union q_util q_util;
if ((3 & (long) lw) == 0 && len == 20) {
sum = (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3] + lw[4];
REDUCE32;
return sum;
}
if ((offset = 3 & (long) lw) != 0) {
const u_int32_t *masks = in_masks + (offset << 2);
lw = (u_int32_t *) (((long) lw) - offset);
sum = *lw++ & masks[len >= 3 ? 3 : len];
len -= 4 - offset;
if (len <= 0) {
REDUCE32;
return sum;
}
}
#if 0
/*
* Force to cache line boundary.
*/
offset = 32 - (0x1f & (long) lw);
if (offset < 32 && len > offset) {
len -= offset;
if (4 & offset) {
sum += (u_int64_t) lw[0];
lw += 1;
}
if (8 & offset) {
sum += (u_int64_t) lw[0] + lw[1];
lw += 2;
}
if (16 & offset) {
sum += (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3];
lw += 4;
}
}
#endif
/*
* access prefilling to start load of next cache line.
* then add current cache line
* save result of prefilling for loop iteration.
*/
prefilled = lw[0];
while ((len -= 32) >= 4) {
u_int64_t prefilling = lw[8];
sum += prefilled + lw[1] + lw[2] + lw[3]
+ lw[4] + lw[5] + lw[6] + lw[7];
lw += 8;
prefilled = prefilling;
}
if (len >= 0) {
sum += prefilled + lw[1] + lw[2] + lw[3]
+ lw[4] + lw[5] + lw[6] + lw[7];
lw += 8;
} else {
len += 32;
}
while ((len -= 16) >= 0) {
sum += (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3];
lw += 4;
}
len += 16;
while ((len -= 4) >= 0) {
sum += (u_int64_t) *lw++;
}
len += 4;
if (len > 0)
sum += (u_int64_t) (in_masks[len] & *lw);
REDUCE32;
return sum;
}
u_short
in_addword(u_short a, u_short b)
{
u_int64_t sum = a + b;
ADDCARRY(sum);
return (sum);
}
u_short
in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c)
{
u_int64_t sum;
union q_util q_util;
union l_util l_util;
sum = (u_int64_t) a + b + c;
REDUCE16;
return (sum);
}
u_short
in_cksum_skip(struct mbuf *m, int len, int skip)
{
u_int64_t sum = 0;
int mlen = 0;
int clen = 0;
caddr_t addr;
union q_util q_util;
union l_util l_util;
len -= skip;
for (; skip && m; m = m->m_next) {
if (m->m_len > skip) {
mlen = m->m_len - skip;
addr = mtod(m, caddr_t) + skip;
goto skip_start;
} else {
skip -= m->m_len;
}
}
for (; m && len; m = m->m_next) {
if (m->m_len == 0)
continue;
mlen = m->m_len;
addr = mtod(m, caddr_t);
skip_start:
if (len < mlen)
mlen = len;
if ((clen ^ (int) addr) & 1)
sum += in_cksumdata(addr, mlen) << 8;
else
sum += in_cksumdata(addr, mlen);
clen += mlen;
len -= mlen;
}
REDUCE16;
return (~sum & 0xffff);
}
u_int in_cksum_hdr(const struct ip *ip)
{
u_int64_t sum = in_cksumdata(ip, sizeof(struct ip));
union q_util q_util;
union l_util l_util;
REDUCE16;
return (~sum & 0xffff);
}

474
sys/arm/arm/in_cksum_arm.S Normal file
View File

@ -0,0 +1,474 @@
/* $NetBSD: in_cksum_arm.S,v 1.2 2003/09/23 10:01:36 scw Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Steve C. Woodford for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Hand-optimised in_cksum() and in4_cksum() implementations for ARM/Xscale
*/
#include "opt_inet.h"
#include <machine/asm.h>
#include "assym.s"
__FBSDID("$FreeBSD$");
/*
* int in_cksum(struct mbuf *m, int len)
*
* Entry:
* r0 m
* r1 len
*
* NOTE: Assumes 'm' is *never* NULL.
*/
/* LINTSTUB: Func: int in_cksum(struct mbuf *, int) */
ENTRY(in_cksum)
stmfd sp!, {r4-r11,lr}
mov r8, #0x00
mov r9, r1
mov r10, #0x00
mov ip, r0
.Lin_cksum_loop:
ldr r1, [ip, #(M_LEN)]
ldr r0, [ip, #(M_DATA)]
ldr ip, [ip, #(M_NEXT)]
.Lin_cksum_entry4:
cmp r9, r1
movlt r1, r9
sub r9, r9, r1
eor r11, r10, r0
add r10, r10, r1
adds r2, r1, #0x00
blne _ASM_LABEL(L_cksumdata)
tst r11, #0x01
movne r2, r2, ror #8
adds r8, r8, r2
adc r8, r8, #0x00
cmp ip, #0x00
bne .Lin_cksum_loop
mov r1, #0xff
orr r1, r1, #0xff00
and r0, r8, r1
add r0, r0, r8, lsr #16
add r0, r0, r0, lsr #16
and r0, r0, r1
eor r0, r0, r1
ldmfd sp!, {r4-r11,pc}
#ifdef INET
/*
* int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len)
*
* Entry:
* r0 m
* r1 nxt
* r2 off
* r3 len
*/
/* LINTSTUB: Func: int in4_cksum(struct mbuf *, u_int8_t, int, int) */
ENTRY(in4_cksum)
stmfd sp!, {r4-r11,lr}
mov r8, #0x00 /* Accumulate sum in r8 */
/*
* First, deal with a pseudo header, if present
*/
ldr r6, [r0, #(M_DATA)]
cmp r1, #0x00
beq .Lin4_cksum_skip_entry
#ifdef __XSCALE__
pld [r6, #(IP_SRC)]
#endif
add r4, r6, #(IP_SRC)
ands r4, r4, #0x03
add r8, r1, r3 /* sum = nxt + len */
addne pc, pc, r4, lsl #5 /* Handle alignment of pseudo header */
nop
/* 0x00: Data 32-bit aligned */
ldr r5, [r6, #(IP_SRC)]
ldr r4, [r6, #(IP_DST)]
b .Lin4_cksum_add_ips
nop
nop
nop
nop
nop
/* 0x01: Data 8-bit aligned */
ldr r4, [r6, #(IP_SRC - 1)] /* BE:r4 = x012 LE:r4 = 210x */
ldr r5, [r6, #(IP_SRC + 3)] /* BE:r5 = 3456 LE:r5 = 6543 */
ldrb r7, [r6, #(IP_SRC + 7)] /* r7 = ...7 */
#ifdef __ARMEB__
mov r4, r4, lsl #8 /* r4 = 012. */
orr r4, r4, r5, lsr #24 /* r4 = 0123 */
orr r5, r7, r5, lsl #8 /* r5 = 4567 */
b .Lin4_cksum_add_ips
nop
#else
mov r4, r4, lsr #8 /* r4 = .210 */
orr r4, r4, r5, lsl #24 /* r4 = 3210 */
mov r5, r5, lsr #8 /* r5 = .654 */
orr r5, r5, r7, lsl #24 /* r5 = 7654 */
b .Lin4_cksum_add_ips
#endif
/* 0x02: Data 16-bit aligned */
#ifdef __XSCALE__
ldrh r5, [r6, #(IP_SRC)] /* BE:r5 = ..01 LE:r5 = ..10 */
ldrh r7, [r6, #(IP_DST + 2)] /* BE:r7 = ..67 LE:r7 = ..76 */
ldr r4, [r6, #(IP_SRC + 2)] /* BE:r4 = 2345 LE:r4 = 5432 */
orr r5, r7, r5, lsl #16 /* BE:r5 = 0167 LE:r5 = 1076 */
b .Lin4_cksum_add_ips
nop
nop
nop
#else
ldr r4, [r6, #(IP_SRC - 2)] /* r4 = 10xx */
ldr r7, [r6, #(IP_DST - 2)] /* r7 = xx76 */
ldr r5, [r6, #(IP_SRC + 2)] /* r5 = 5432 */
mov r4, r4, lsr #16 /* r4 = ..10 */
orr r4, r4, r7, lsl #16 /* r4 = 7610 */
b .Lin4_cksum_add_ips
nop
nop
#endif
/* 0x03: Data 8-bit aligned */
ldrb r4, [r6, #(IP_SRC)] /* r4 = ...0 */
ldr r5, [r6, #(IP_SRC + 1)] /* BE:r5 = 1234 LE:r5 = 4321 */
ldr r7, [r6, #(IP_SRC + 5)] /* BE:r7 = 567x LE:r7 = x765 */
#ifdef __ARMEB__
mov r4, r4, lsl #24 /* r4 = 0... */
orr r4, r4, r5, lsr #8 /* r4 = 0123 */
mov r5, r5, lsl #24 /* r5 = 4... */
orr r5, r5, r7, lsr #8 /* r5 = 4567 */
#else
orr r4, r4, r5, lsl #8 /* r4 = 3210 */
mov r5, r5, lsr #24 /* r4 = ...4 */
orr r5, r5, r7, lsl #8 /* r5 = 7654 */
#endif
/* FALLTHROUGH */
.Lin4_cksum_add_ips:
adds r5, r5, r4
#ifndef __ARMEB__
adcs r8, r5, r8, lsl #8
#else
adcs r8, r5, r8
#endif
adc r8, r8, #0x00
mov r1, #0x00
b .Lin4_cksum_skip_entry
.Lin4_cksum_skip_loop:
ldr r1, [r0, #(M_LEN)]
ldr r6, [r0, #(M_DATA)]
ldr r0, [r0, #(M_NEXT)]
.Lin4_cksum_skip_entry:
subs r2, r2, r1
blt .Lin4_cksum_skip_done
cmp r0, #0x00
bne .Lin4_cksum_skip_loop
b .Lin4_cksum_whoops
.Lin4_cksum_skip_done:
mov ip, r0
add r0, r2, r6
add r0, r0, r1
rsb r1, r2, #0x00
mov r9, r3
mov r10, #0x00
b .Lin_cksum_entry4
.Lin4_cksum_whoops:
adr r0, .Lin4_cksum_whoops_str
adr r1, .LFile
mov r2, #__LINE__
bl _C_LABEL(__panic)
.LFile:
.asciz __FILE__
.Lin4_cksum_whoops_str:
.asciz "in4_cksum: out of mbufs\n"
.align 5
#endif /* INET */
/*
* The main in*_cksum() workhorse...
*
* Entry parameters:
* r0 Pointer to buffer
* r1 Buffer length
* lr Return address
*
* Returns:
* r2 Accumulated 32-bit sum
*
* Clobbers:
* r0-r7
*/
/* LINTSTUB: Ignore */
ASENTRY_NP(L_cksumdata)
#ifdef __XSCALE__
pld [r0] /* Pre-fetch the start of the buffer */
#endif
mov r2, #0
/* We first have to word-align the buffer. */
ands r7, r0, #0x03
beq .Lcksumdata_wordaligned
rsb r7, r7, #0x04
cmp r1, r7 /* Enough bytes left to make it? */
blt .Lcksumdata_endgame
cmp r7, #0x02
ldrb r4, [r0], #0x01 /* Fetch 1st byte */
ldrgeb r5, [r0], #0x01 /* Fetch 2nd byte */
movlt r5, #0x00
ldrgtb r6, [r0], #0x01 /* Fetch 3rd byte */
movle r6, #0x00
/* Combine the three bytes depending on endianness and alignment */
#ifdef __ARMEB__
orreq r2, r5, r4, lsl #8
orreq r2, r2, r6, lsl #24
orrne r2, r4, r5, lsl #8
orrne r2, r2, r6, lsl #16
#else
orreq r2, r4, r5, lsl #8
orreq r2, r2, r6, lsl #16
orrne r2, r5, r4, lsl #8
orrne r2, r2, r6, lsl #24
#endif
subs r1, r1, r7 /* Update length */
moveq pc, lr /* All done? */
/* Buffer is now word aligned */
.Lcksumdata_wordaligned:
#ifdef __XSCALE__
cmp r1, #0x04 /* Less than 4 bytes left? */
blt .Lcksumdata_endgame /* Yup */
/* Now quad-align, if necessary */
ands r7, r0, #0x04
ldrne r7, [r0], #0x04
subne r1, r1, #0x04
subs r1, r1, #0x40
blt .Lcksumdata_bigloop_end /* Note: C flag clear if branch taken */
/*
* Buffer is now quad aligned. Sum 64 bytes at a time.
* Note: First ldrd is hoisted above the loop, together with
* setting r6 to zero to avoid stalling for results in the
* loop. (r7 is live, from above).
*/
ldrd r4, [r0], #0x08
mov r6, #0x00
.Lcksumdata_bigloop:
pld [r0, #0x18]
adds r2, r2, r6
adcs r2, r2, r7
ldrd r6, [r0], #0x08
adcs r2, r2, r4
adcs r2, r2, r5
ldrd r4, [r0], #0x08
adcs r2, r2, r6
adcs r2, r2, r7
ldrd r6, [r0], #0x08
adcs r2, r2, r4
adcs r2, r2, r5
ldrd r4, [r0], #0x08
adcs r2, r2, r6
adcs r2, r2, r7
pld [r0, #0x18]
ldrd r6, [r0], #0x08
adcs r2, r2, r4
adcs r2, r2, r5
ldrd r4, [r0], #0x08
adcs r2, r2, r6
adcs r2, r2, r7
ldrd r6, [r0], #0x08
adcs r2, r2, r4
adcs r2, r2, r5
adc r2, r2, #0x00
subs r1, r1, #0x40
ldrged r4, [r0], #0x08
bge .Lcksumdata_bigloop
adds r2, r2, r6 /* r6/r7 still need summing */
.Lcksumdata_bigloop_end:
adcs r2, r2, r7
adc r2, r2, #0x00
#else /* !__XSCALE__ */
subs r1, r1, #0x40
blt .Lcksumdata_bigloop_end
.Lcksumdata_bigloop:
ldmia r0!, {r3, r4, r5, r6}
adds r2, r2, r3
adcs r2, r2, r4
adcs r2, r2, r5
ldmia r0!, {r3, r4, r5, r7}
adcs r2, r2, r6
adcs r2, r2, r3
adcs r2, r2, r4
adcs r2, r2, r5
ldmia r0!, {r3, r4, r5, r6}
adcs r2, r2, r7
adcs r2, r2, r3
adcs r2, r2, r4
adcs r2, r2, r5
ldmia r0!, {r3, r4, r5, r7}
adcs r2, r2, r6
adcs r2, r2, r3
adcs r2, r2, r4
adcs r2, r2, r5
adcs r2, r2, r7
adc r2, r2, #0x00
subs r1, r1, #0x40
bge .Lcksumdata_bigloop
.Lcksumdata_bigloop_end:
#endif
adds r1, r1, #0x40
moveq pc, lr
cmp r1, #0x20
#ifdef __XSCALE__
ldrged r4, [r0], #0x08 /* Avoid stalling pld and result */
blt .Lcksumdata_less_than_32
pld [r0, #0x18]
ldrd r6, [r0], #0x08
adds r2, r2, r4
adcs r2, r2, r5
ldrd r4, [r0], #0x08
adcs r2, r2, r6
adcs r2, r2, r7
ldrd r6, [r0], #0x08
adcs r2, r2, r4
adcs r2, r2, r5
adcs r2, r2, r6 /* XXX: Unavoidable result stall */
adcs r2, r2, r7
#else
blt .Lcksumdata_less_than_32
ldmia r0!, {r3, r4, r5, r6}
adds r2, r2, r3
adcs r2, r2, r4
adcs r2, r2, r5
ldmia r0!, {r3, r4, r5, r7}
adcs r2, r2, r6
adcs r2, r2, r3
adcs r2, r2, r4
adcs r2, r2, r5
adcs r2, r2, r7
#endif
adc r2, r2, #0x00
subs r1, r1, #0x20
moveq pc, lr
.Lcksumdata_less_than_32:
/* There are less than 32 bytes left */
and r3, r1, #0x18
rsb r4, r3, #0x18
sub r1, r1, r3
adds r4, r4, r4, lsr #1 /* Side effect: Clear carry flag */
addne pc, pc, r4
nop
/*
* Note: We use ldm here, even on Xscale, since the combined issue/result
* latencies for ldm and ldrd are the same. Using ldm avoids needless #ifdefs.
*/
/* At least 24 bytes remaining... */
ldmia r0!, {r4, r5}
adcs r2, r2, r4
adcs r2, r2, r5
/* At least 16 bytes remaining... */
ldmia r0!, {r4, r5}
adcs r2, r2, r4
adcs r2, r2, r5
/* At least 8 bytes remaining... */
ldmia r0!, {r4, r5}
adcs r2, r2, r4
adcs r2, r2, r5
/* Less than 8 bytes remaining... */
adc r2, r2, #0x00
subs r1, r1, #0x04
blt .Lcksumdata_lessthan4
ldr r4, [r0], #0x04
sub r1, r1, #0x04
adds r2, r2, r4
adc r2, r2, #0x00
/* Deal with < 4 bytes remaining */
.Lcksumdata_lessthan4:
adds r1, r1, #0x04
moveq pc, lr
/* Deal with 1 to 3 remaining bytes, possibly misaligned */
.Lcksumdata_endgame:
ldrb r3, [r0] /* Fetch first byte */
cmp r1, #0x02
ldrgeb r4, [r0, #0x01] /* Fetch 2nd and 3rd as necessary */
movlt r4, #0x00
ldrgtb r5, [r0, #0x02]
movle r5, #0x00
/* Combine the three bytes depending on endianness and alignment */
tst r0, #0x01
#ifdef __ARMEB__
orreq r3, r4, r3, lsl #8
orreq r3, r3, r5, lsl #24
orrne r3, r3, r4, lsl #8
orrne r3, r3, r5, lsl #16
#else
orreq r3, r3, r4, lsl #8
orreq r3, r3, r5, lsl #16
orrne r3, r4, r3, lsl #8
orrne r3, r3, r5, lsl #24
#endif
adds r2, r2, r3
adc r2, r2, #0x00
mov pc, lr

150
sys/arm/arm/intr.c Normal file
View File

@ -0,0 +1,150 @@
/* $NetBSD: intr.c,v 1.12 2003/07/15 00:24:41 lukem Exp $ */
/*
* Copyright (c) 2004 Olivier Houchard.
* Copyright (c) 1994-1998 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe
* for the NetBSD Project.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Soft interrupt and other generic interrupt functions.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/conf.h>
#include <machine/atomic.h>
#include <machine/intr.h>
#include <machine/cpu.h>
int current_spl_level = _SPL_SERIAL;
u_int spl_masks[_SPL_LEVELS + 1];
u_int spl_smasks[_SPL_LEVELS];
extern u_int irqmasks[];
#define NIRQ 0x20 /* XXX */
struct ithd *ithreads[NIRQ];
void
set_splmasks()
{
int loop;
for (loop = 0; loop < _SPL_LEVELS; ++loop) {
spl_masks[loop] = 0xffffffff;
spl_smasks[loop] = 1;
}
spl_masks[_SPL_NET] = irqmasks[IPL_NET];
spl_masks[_SPL_SOFTSERIAL] = irqmasks[IPL_TTY];
spl_masks[_SPL_TTY] = irqmasks[IPL_TTY];
spl_masks[_SPL_VM] = irqmasks[IPL_VM];
spl_masks[_SPL_AUDIO] = irqmasks[IPL_AUDIO];
spl_masks[_SPL_CLOCK] = irqmasks[IPL_CLOCK];
#ifdef IPL_STATCLOCK
spl_masks[_SPL_STATCLOCK] = irqmasks[IPL_STATCLOCK];
#else
spl_masks[_SPL_STATCLOCK] = irqmasks[IPL_CLOCK];
#endif
spl_masks[_SPL_HIGH] = irqmasks[IPL_HIGH];
spl_masks[_SPL_SERIAL] = irqmasks[IPL_SERIAL];
spl_masks[_SPL_LEVELS] = 0;
spl_smasks[_SPL_0] = 0xffffffff;
for (loop = 0; loop < _SPL_SOFTSERIAL; ++loop)
spl_smasks[loop] |= SOFTIRQ_BIT(SOFTIRQ_SERIAL);
for (loop = 0; loop < _SPL_SOFTNET; ++loop)
spl_smasks[loop] |= SOFTIRQ_BIT(SOFTIRQ_NET);
for (loop = 0; loop < _SPL_SOFTCLOCK; ++loop)
spl_smasks[loop] |= SOFTIRQ_BIT(SOFTIRQ_CLOCK);
}
void arm_setup_irqhandler(const char *name, void (*hand)(void*), void *arg,
int irq, int flags, void **cookiep)
{
struct ithd *cur_ith;
int error;
if (irq < 0 || irq >= NIRQ)
return;
cur_ith = ithreads[irq];
if (cur_ith == NULL) {
error = ithread_create(&cur_ith, irq, 0, NULL, NULL, "intr%d:",
irq);
if (error)
return;
ithreads[irq] = cur_ith;
}
ithread_add_handler(cur_ith, name, hand, arg, ithread_priority(flags),
flags, cookiep);
}
void dosoftints(void);
void
dosoftints(void)
{
}
void
arm_handler_execute(void *);
void
arm_handler_execute(void *irq)
{
struct ithd *ithd;
int i;
int irqnb = (int)irq;
struct intrhand *ih;
for (i = 0; i < NIRQ; i++) {
if (1 << i & irqnb) {
ithd = ithreads[i];
if (!ithd) /* FUCK */
return;
ih = TAILQ_FIRST(&ithd->it_handlers);
if (ih && ih->ih_flags & IH_FAST) {
TAILQ_FOREACH(ih, &ithd->it_handlers,
ih_next) {
ih->ih_handler(ih->ih_argument);
/*
* XXX: what about the irq frame if
* the arg is NULL ?
*/
}
} else if (ih) {
ithread_schedule(ithd, !cold);
}
}
}
}

155
sys/arm/arm/irq_dispatch.S Normal file
View File

@ -0,0 +1,155 @@
/* $NetBSD: irq_dispatch.S,v 1.5 2003/10/30 08:57:24 scw Exp $ */
/*
* Copyright (c) 2002 Fujitsu Component Limited
* Copyright (c) 2002 Genetec Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Fujitsu Component Limited nor the name of
* Genetec corporation may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
* CORPORATION ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL FUJITSU COMPONENT LIMITED OR GENETEC
* CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/*
* Copyright (c) 2002, 2003 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "assym.s"
#include <machine/asm.h>
#include <machine/asmacros.h>
#include <machine/armreg.h>
__FBSDID("$FreeBSD$");
#if 0
#ifdef ARM_INTR_IMPL
#include ARM_INTR_IMPL
#else
#error ARM_INTR_IMPL not defined
#endif
#ifndef ARM_IRQ_HANDLER
#error ARM_IRQ_HANDLER not defined
#endif
#endif
/*
* irq_entry:
* Main entry point for the IRQ vector. This is a generic version
* which can be used by different platforms.
*/
.text
.align 0
.Lcurrent_intr_depth:
.word _C_LABEL(current_intr_depth)
AST_ALIGNMENT_FAULT_LOCALS
ASENTRY_NP(irq_entry)
sub lr, lr, #0x00000004 /* Adjust the lr */
PUSHFRAMEINSVC /* Push an interrupt frame */
ENABLE_ALIGNMENT_FAULTS
ldr r1, .Laflt_curpcb
/*
* Increment the interrupt nesting depth and call the interrupt
* dispatch routine. We've pushed a frame, so we can safely use
* callee-saved regs here. We use the following registers, which
* we expect to presist:
*
* r5 address of `current_intr_depth' variable
* r6 old value of `current_intr_depth'
*/
ldr r5, .Lcurrent_intr_depth
mov r0, sp /* arg for dispatcher */
ldr r6, [r5]
add r1, r6, #1
str r1, [r5]
#if 0
bl ARM_IRQ_HANDLER
#endif
/*
* Restore the old interrupt depth value (which should be the
* same as decrementing it at this point).
*/
str r6, [r5]
DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
PULLFRAMEFROMSVCANDEXIT
movs pc, lr /* Exit */
.bss
.align 0
.global _C_LABEL(current_intr_depth)
_C_LABEL(current_intr_depth):
.word 0
/*
* XXX Provide intrnames/intrcnt for legacy code, but
* don't actually use them.
*/
.global _C_LABEL(intrnames), _C_LABEL(eintrnames)
.global _C_LABEL(intrcnt), _C_LABEL(eintrcnt)
_C_LABEL(intrnames):
_C_LABEL(eintrnames):
.global _C_LABEL(intrcnt), _C_LABEL(sintrcnt), _C_LABEL(eintrcnt)
_C_LABEL(intrcnt):
_C_LABEL(eintrcnt):

312
sys/arm/arm/locore.S Normal file
View File

@ -0,0 +1,312 @@
/* $NetBSD: locore.S,v 1.14 2003/04/20 16:21:40 thorpej Exp $ */
/*
* Copyright (C) 1994-1997 Mark Brinicombe
* Copyright (C) 1994 Brini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of Brini may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "assym.s"
#include <machine/asm.h>
#include <machine/armreg.h>
#include <machine/pte.h>
__FBSDID("$FreeBSD$");
/* What size should this really be ? It is only used by init_arm() */
#define INIT_ARM_STACK_SIZE 2048
/*
* This is for kvm_mkdb, and should be the address of the beginning
* of the kernel text segment (not necessarily the same as kernbase).
*/
#define CPWAIT_BRANCH \
sub pc, pc, #4
#define CPWAIT(tmp) \
mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\
mov tmp, tmp /* wait for it to complete */ ;\
CPWAIT_BRANCH /* branch to next insn */
.text
.align 0
.globl kernbase
.set kernbase,KERNBASE
ENTRY_NP(btext)
ASENTRY_NP(_start)
/* Check if we are running on RAM, if not move ourself to RAM */
cmp pc, #KERNPHYSADDR
bhi start_inram /* XXX: This is wrong */
/* move me to RAM
* XXX: we can use memcpy if it is PIC
*/
ldr r1, Lcopy_size
adr r0, _C_LABEL(_start)
add r1, r1, #3
mov r1, r1, LSR #2
mov r2, #KERNPHYSADDR
add r2, r2, #0x00200000
mov r4, r2
5: ldr r3,[r0],#4
str r3,[r2],#4
subs r1,r1,#1
bhi 5b
/* Jump to RAM */
ldr r0, Lstart_off
add pc, r4, r0
Lcopy_size: .word _edata-_C_LABEL(_start)
Lstart_off: .word start_inram-_C_LABEL(_start)
start_inram:
#ifdef STARTUP_PAGETABLE_ADDR
adr r4, mmu_init_table2
mrc p15, 0, r2, c1, c0, 0
tst r2, #CPU_CONTROL_MMU_ENABLE /* we already have a page table? */
bne 3f
/* build page table from scratch */
ldr r0, Lstartup_pagetable
adr r4, mmu_init_table
b 3f
2:
str r3, [r0, r2]
add r2, r2, #4
add r3, r3, #(L1_S_SIZE)
adds r1, r1, #-1
bhi 2b
3:
ldmia r4!, {r1,r2,r3} /* # of sections, PA|attr, VA */
cmp r1, #0
bne 2b
mcr p15, 0, r0, c2, c0, 0 /* Set TTB */
mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */
/* Set the Domain Access register. Very important! */
mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
mcr p15, 0, r0, c3, c0, 0
/* Enable MMU */
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #CPU_CONTROL_MMU_ENABLE
mcr p15, 0, r0, c1, c0, 0
CPWAIT(r0)
bl mmu_done
mmu_done:
#endif
adr r1, .Lstart
ldmia r1, {r1, r2, sp} /* Set initial stack and */
sub r2, r2, r1 /* get zero init data */
mov r3, #0
.L1:
str r3, [r1], #0x0004 /* Zero the bss */
subs r2, r2, #4
bgt .L1
mov fp, #0xc0000000 /* trace back starts here */
bl _C_LABEL(initarm) /* Off we go */
/* init arm will return the new stack pointer. */
mov sp, r0
mov fp, #0x00000000 /* trace back starts here */
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
bl _C_LABEL(mi_startup) /* call mi_startup()! */
adr r0, .Lmainreturned
adr r1, .LFile
mov r2, #__LINE__
b _C_LABEL(__panic)
/* NOTEACHED */
#ifdef STARTUP_PAGETABLE_ADDR
#define MMU_INIT(va,pa,n_sec,attr) \
.word n_sec ; \
.word 4*((va)>>L1_S_SHIFT) ; \
.word (pa)|(attr) ;
Lstartup_pagetable:
.word STARTUP_PAGETABLE_ADDR
mmu_init_table:
/* fill all table VA==PA */
MMU_INIT(0x00000000, 0x00000000, 1<<(32-L1_S_SHIFT), L1_TYPE_S|L1_S_AP(AP_KRW))
/* map SDRAM VA==PA, WT cacheable */
MMU_INIT(KERNPHYSADDR, KERNPHYSADDR, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
mmu_init_table2:
/* map VA 0xc0000000..0xc3ffffff to PA 0xa0000000..0xa3ffffff */
MMU_INIT(0xc0000000, KERNPHYSADDR, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
.word 0 /* end of table */
#endif
.Lstart:
.word _edata
.word _end
.word svcstk + INIT_ARM_STACK_SIZE
.LFile:
.asciz __FILE__
.Lmainreturned:
.asciz "main() returned"
.align 0
.bss
svcstk:
.space INIT_ARM_STACK_SIZE
.text
.align 0
#ifndef OFW
/* OFW based systems will used OF_boot() */
.Lcpufuncs:
.word _C_LABEL(cpufuncs)
ENTRY_NP(cpu_reset)
mrs r2, cpsr
bic r2, r2, #(PSR_MODE)
orr r2, r2, #(PSR_SVC32_MODE)
orr r2, r2, #(I32_bit | F32_bit)
msr cpsr_all, r2
ldr r4, .Lcpu_reset_address
ldr r4, [r4]
ldr r0, .Lcpufuncs
mov lr, pc
ldr pc, [r0, #CF_IDCACHE_WBINV_ALL]
/*
* Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's
* necessary.
*/
ldr r1, .Lcpu_reset_needs_v4_MMU_disable
ldr r1, [r1]
cmp r1, #0
mov r2, #0
/*
* MMU & IDC off, 32 bit program & data space
* Hurl ourselves into the ROM
*/
mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE)
mcr 15, 0, r0, c1, c0, 0
mcrne 15, 0, r2, c8, c7, 0 /* nail I+D TLB on ARMv4 and greater */
mov pc, r4
/*
* _cpu_reset_address contains the address to branch to, to complete
* the cpu reset after turning the MMU off
* This variable is provided by the hardware specific code
*/
.Lcpu_reset_address:
.word _C_LABEL(cpu_reset_address)
/*
* cpu_reset_needs_v4_MMU_disable contains a flag that signals if the
* v4 MMU disable instruction needs executing... it is an illegal instruction
* on f.e. ARM6/7 that locks up the computer in an endless illegal
* instruction / data-abort / reset loop.
*/
.Lcpu_reset_needs_v4_MMU_disable:
.word _C_LABEL(cpu_reset_needs_v4_MMU_disable)
#endif /* OFW */
#ifdef IPKDB
/*
* Execute(inst, psr, args, sp)
*
* Execute INSTruction with PSR and ARGS[0] - ARGS[3] making
* available stack at SP for next undefined instruction trap.
*
* Move the instruction onto the stack and jump to it.
*/
ENTRY_NP(Execute)
mov ip, sp
stmfd sp!, {r2, r4-r7, fp, ip, lr, pc}
sub fp, ip, #4
mov ip, r3
ldr r7, .Lreturn
stmfd sp!, {r0, r7}
adr r7, #.LExec
mov r5, r1
mrs r4, cpsr
ldmia r2, {r0-r3}
mov r6, sp
mov sp, ip
msr cpsr_all, r5
mov pc, r6
.LExec:
mrs r5, cpsr
/* XXX Cannot switch thus easily back from user mode */
msr cpsr_all, r4
add sp, r6, #8
ldmfd sp!, {r6}
stmia r6, {r0-r3}
mov r0, r5
ldmdb fp, {r4-r7, fp, sp, pc}
.Lreturn:
mov pc, r7
#endif
/*
* setjump + longjmp
*/
ENTRY(setjmp)
stmia r0, {r4-r14}
mov r0, #0x00000000
mov pc, lr
ENTRY(longjmp)
ldmia r0, {r4-r14}
mov r0, #0x00000001
mov pc, lr
.data
.global _C_LABEL(esym)
_C_LABEL(esym): .word _C_LABEL(end)
ENTRY_NP(abort)
b _C_LABEL(abort)
/* End of locore.S */

409
sys/arm/arm/machdep.c Normal file
View File

@ -0,0 +1,409 @@
/* $NetBSD: arm32_machdep.c,v 1.44 2004/03/24 15:34:47 atatat Exp $ */
/*
* Copyright (c) 2004 Olivier Houchard
* Copyright (c) 1994-1998 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe
* for the NetBSD Project.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Machine dependant functions for kernel setup
*
* Created : 17/09/94
* Updated : 18/04/01 updated for new wscons
*/
#include "opt_compat.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/signalvar.h>
#include <sys/imgact.h>
#include <sys/kernel.h>
#include <sys/linker.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/pcpu.h>
#include <sys/proc.h>
#include <sys/ptrace.h>
#include <sys/cons.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/exec.h>
#include <machine/reg.h>
#include <machine/cpu.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pager.h>
#include <vm/vm_map.h>
#include <vm/vnode_pager.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/undefined.h>
#include <machine/machdep.h>
#include <machine/metadata.h>
#include <machine/armreg.h>
#define MDROOT_ADDR 0xd0400000
uint32_t cpu_reset_address = 0;
int cold = 1;
int astpending = 0;
vm_offset_t vector_page;
static void *
getframe(struct thread *td, int sig, int *onstack)
{
struct trapframe *tf = td->td_frame;
*onstack = sigonstack(tf->tf_usr_sp);
if (*onstack)
return (void*)(td->td_sigstk.ss_sp + td->td_sigstk.ss_size);
return (void*)(tf->tf_usr_sp);
}
void
sendsig(catcher, sig, mask, code)
sig_t catcher;
int sig;
sigset_t *mask;
u_long code;
{
struct thread *td = curthread;
struct trapframe *tf = td->td_frame;
struct sigframe *fp, frame;
struct sigacts *psp = td->td_proc->p_sigacts;
int onstack;
fp = getframe(td, sig, &onstack);
/* make room on the stack */
fp--;
/* make the stack aligned */
(u_int)fp = _ALIGN(fp);
/* Populate the siginfo frame. */
frame.sf_si.si_signo = sig;
frame.sf_si.si_code = code;
frame.sf_uc.uc_sigmask = *mask;
frame.sf_uc.uc_link = NULL;
frame.sf_uc.uc_flags |= td->td_sigstk.ss_flags & SS_ONSTACK ?
_UC_SETSTACK : _UC_CLRSTACK;
memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack));
get_mcontext(td, &frame.sf_uc.uc_mcontext,
(uint32_t)&frame.sf_uc.uc_flags);
PROC_UNLOCK(td->td_proc);
mtx_unlock(&psp->ps_mtx);
if (copyout(&frame, (void*)fp, sizeof(frame)) != 0)
sigexit(td, SIGILL);
/*
* Build context to run handler in. We invoke the handler
* directly, only returning via the trampoline. Note the
* trampoline version numbers are coordinated with machine-
* dependent code in libc.
*/
tf->tf_r0 = sig;
tf->tf_r1 = (int)&fp->sf_si;
tf->tf_r2 = (int)&fp->sf_uc;
/* the trampoline uses r5 as the uc address */
tf->tf_r5 = (int)&fp->sf_uc;
tf->tf_pc = (int)catcher;
tf->tf_usr_sp = (int)fp;
if (onstack)
td->td_sigstk.ss_flags |= SS_ONSTACK;
PROC_LOCK(td->td_proc);
mtx_lock(&psp->ps_mtx);
}
struct kva_md_info kmi;
/*
* arm32_vector_init:
*
* Initialize the vector page, and select whether or not to
* relocate the vectors.
*
* NOTE: We expect the vector page to be mapped at its expected
* destination.
*/
extern unsigned int page0[], page0_data[];
void
arm_vector_init(vm_offset_t va, int which)
{
unsigned int *vectors = (int *) va;
unsigned int *vectors_data = vectors + (page0_data - page0);
int vec;
/*
* Loop through the vectors we're taking over, and copy the
* vector's insn and data word.
*/
for (vec = 0; vec < ARM_NVEC; vec++) {
if ((which & (1 << vec)) == 0) {
/* Don't want to take over this vector. */
continue;
}
vectors[vec] = page0[vec];
vectors_data[vec] = page0_data[vec];
}
/* Now sync the vectors. */
cpu_icache_sync_range(va, (ARM_NVEC * 2) * sizeof(u_int));
vector_page = va;
if (va == ARM_VECTORS_HIGH) {
/*
* Assume the MD caller knows what it's doing here, and
* really does want the vector page relocated.
*
* Note: This has to be done here (and not just in
* cpu_setup()) because the vector page needs to be
* accessible *before* cpu_startup() is called.
* Think ddb(9) ...
*
* NOTE: If the CPU control register is not readable,
* this will totally fail! We'll just assume that
* any system that has high vector support has a
* readable CPU control register, for now. If we
* ever encounter one that does not, we'll have to
* rethink this.
*/
cpu_control(CPU_CONTROL_VECRELOC, CPU_CONTROL_VECRELOC);
}
}
static void
cpu_startup(void *dummy)
{
struct pcb *pcb = thread0.td_pcb;
vm_ksubmap_init(&kmi);
bufinit();
vm_pager_bufferinit();
pcb->un_32.pcb32_und_sp = (u_int)thread0.td_kstack +
USPACE_UNDEF_STACK_TOP;
pcb->un_32.pcb32_sp = (u_int)thread0.td_kstack +
USPACE_SVC_STACK_TOP;
vector_page_setprot(VM_PROT_READ);
pmap_update(pmap_kernel());
pmap_set_pcb_pagedir(pmap_kernel(), pcb);
cpu_setup("");
identify_arm_cpu();
thread0.td_frame = (struct trapframe *)pcb->un_32.pcb32_sp - 1;
}
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
void
cpu_idle(void)
{
}
int
fill_regs(struct thread *td, struct reg *regs)
{
struct trapframe *tf = td->td_frame;
bcopy(&tf->tf_r0, regs->r, sizeof(regs->r));
regs->r_sp = tf->tf_usr_sp;
regs->r_lr = tf->tf_usr_lr;
regs->r_pc = tf->tf_pc;
regs->r_cpsr = tf->tf_spsr;
return (0);
}
int
fill_fpregs(struct thread *td, struct fpreg *regs)
{
bzero(regs, sizeof(*regs));
return (0);
}
int
set_regs(struct thread *td, struct reg *regs)
{
struct trapframe *tf = td->td_frame;
bcopy(regs->r, &tf->tf_r0, sizeof(*regs->r));
tf->tf_usr_sp = regs->r_sp;
tf->tf_usr_lr = regs->r_lr;
tf->tf_pc = regs->r_pc;
tf->tf_spsr &= ~PSR_FLAGS;
tf->tf_spsr |= regs->r_cpsr & PSR_FLAGS;
while(1);
return (0);
}
int
set_fpregs(struct thread *td, struct fpreg *regs)
{
return (0);
}
int
fill_dbregs(struct thread *td, struct dbreg *regs)
{
return (0);
}
int
set_dbregs(struct thread *td, struct dbreg *regs)
{
return (0);
}
void
cpu_halt(void)
{
cpu_reset();
}
int
ptrace_single_step(struct thread *td)
{
return (0);
}
int
ptrace_set_pc(struct thread *td, unsigned long addr)
{
return (0);
}
void
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
{
}
/*
* Clear registers on exec
*/
void
exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
{
struct trapframe *tf = td->td_frame;
memset(tf, 0, sizeof(*tf));
tf->tf_usr_sp = stack;
tf->tf_usr_lr = entry;
tf->tf_svc_lr = 0x77777777;
tf->tf_pc = entry;
tf->tf_spsr = PSR_USR32_MODE;
}
/*
* Build siginfo_t for SA thread
*/
void
cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
{
printf("cpu_thread_siginfo\n");
}
/*
* Get machine context.
*/
int
get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
{
struct trapframe *tf = td->td_frame;
__greg_t *gr = mcp->__gregs;
/* Save General Register context. */
gr[_REG_R0] = tf->tf_r0;
gr[_REG_R1] = tf->tf_r1;
gr[_REG_R2] = tf->tf_r2;
gr[_REG_R3] = tf->tf_r3;
gr[_REG_R4] = tf->tf_r4;
gr[_REG_R5] = tf->tf_r5;
gr[_REG_R6] = tf->tf_r6;
gr[_REG_R7] = tf->tf_r7;
gr[_REG_R8] = tf->tf_r8;
gr[_REG_R9] = tf->tf_r9;
gr[_REG_R10] = tf->tf_r10;
gr[_REG_R11] = tf->tf_r11;
gr[_REG_R12] = tf->tf_r12;
gr[_REG_SP] = tf->tf_usr_sp;
gr[_REG_LR] = tf->tf_usr_lr;
gr[_REG_PC] = tf->tf_pc;
gr[_REG_CPSR] = tf->tf_spsr;
return (0);
}
/*
* Set machine context.
*
* However, we don't set any but the user modifiable flags, and we won't
* touch the cs selector.
*/
int
set_mcontext(struct thread *td, const mcontext_t *mcp)
{
panic("SET_MCONTEXT AHAHAH\n");
return (0);
}
#ifdef COMPAT_FREEBSD4
int
freebsd4_sigreturn(td, uap)
struct thread *td;
struct freebsd4_sigreturn_args /* {
const ucontext4 *sigcntxp;
} */ *uap;
{
return (0);
}
#endif
/*
* MPSAFE
*/
int
sigreturn(td, uap)
struct thread *td;
struct sigreturn_args /* {
const __ucontext *sigcntxp;
} */ *uap;
{
return (0);
}

243
sys/arm/arm/nexus.c Normal file
View File

@ -0,0 +1,243 @@
/*
* Copyright 1998 Massachusetts Institute of Technology
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
* granted, provided that both the above copyright notice and this
* permission notice appear in all copies, that both the above
* copyright notice and this permission notice appear in all
* supporting documentation, and that the name of M.I.T. not be used
* in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. M.I.T. makes
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
* ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
* SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/*
* This code implements a `root nexus' for Arm Architecture
* machines. The function of the root nexus is to serve as an
* attachment point for both processors and buses, and to manage
* resources which are common to all of them. In particular,
* this code implements the core resource managers for interrupt
* requests, DMA requests (which rightfully should be a part of the
* ISA code but it's easier to do it here for now), I/O port addresses,
* and I/O memory address space.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/interrupt.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/pmap.h>
#include <machine/resource.h>
#include <machine/intr.h>
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
struct nexus_device {
struct resource_list nx_resources;
};
#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev))
static struct rman mem_rman;
static int nexus_probe(device_t);
static int nexus_attach(device_t);
static int nexus_print_child(device_t, device_t);
static device_t nexus_add_child(device_t, int, const char *, int);
static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
u_long, u_long, u_long, u_int);
static int nexus_activate_resource(device_t, device_t, int, int,
struct resource *);
static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
driver_intr_t *intr, void *arg, void **cookiep);
static device_method_t nexus_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, nexus_probe),
DEVMETHOD(device_attach, nexus_attach),
/* Bus interface */
DEVMETHOD(bus_print_child, nexus_print_child),
DEVMETHOD(bus_add_child, nexus_add_child),
DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
DEVMETHOD(bus_activate_resource, nexus_activate_resource),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
{ 0, 0 }
};
static driver_t nexus_driver = {
"nexus",
nexus_methods,
1 /* no softc */
};
static devclass_t nexus_devclass;
static int
nexus_probe(device_t dev)
{
device_quiet(dev); /* suppress attach message for neatness */
mem_rman.rm_start = 0;
mem_rman.rm_end = ~0u;
mem_rman.rm_type = RMAN_ARRAY;
mem_rman.rm_descr = "I/O memory addresses";
if (rman_init(&mem_rman)
|| rman_manage_region(&mem_rman, 0, ~0u))
panic("nexus_probe mem_rman");
return (0);
return bus_generic_probe(dev);
}
static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
driver_intr_t *intr, void *arg, void **cookiep)
{
arm_setup_irqhandler(device_get_nameunit(child),
intr, arg, res->r_start, flags, cookiep);
return (0);
}
static int
nexus_attach(device_t dev)
{
/*
* First, deal with the children we know about already
*/
printf("avant\n");
bus_generic_probe(dev);
bus_generic_attach(dev);
printf("nexus_attach\n");
return 0;
}
static int
nexus_print_child(device_t bus, device_t child)
{
int retval = 0;
retval += bus_print_child_header(bus, child);
retval += printf(" on motherboard\n"); /* XXX "motherboard", ick */
return (retval);
}
static device_t
nexus_add_child(device_t bus, int order, const char *name, int unit)
{
device_t child;
struct nexus_device *ndev;
ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO);
if (!ndev)
return(0);
resource_list_init(&ndev->nx_resources);
child = device_add_child_ordered(bus, order, name, unit);
/* should we free this in nexus_child_detached? */
device_set_ivars(child, ndev);
return(child);
}
/*
* Allocate a resource on behalf of child. NB: child is usually going to be a
* child of one of our descendants, not a direct child of nexus0.
* (Exceptions include footbridge.)
*/
#define ARM_BUS_SPACE_MEM 1
static struct resource *
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct resource *rv;
struct rman *rm;
int needactivate = flags & RF_ACTIVE;
switch (type) {
case SYS_RES_MEMORY:
rm = &mem_rman;
break;
default:
return 0;
}
rv = rman_reserve_resource(rm, start, end, count, flags, child);
if (rv == 0)
return 0;
rman_set_bustag(rv, (void*)ARM_BUS_SPACE_MEM);
rman_set_bushandle(rv, rv->r_start);
if (needactivate) {
if (bus_activate_resource(child, type, *rid, rv)) {
rman_release_resource(rv);
return 0;
}
}
return rv;
}
static int
nexus_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
/*
* If this is a memory resource, map it into the kernel.
*/
if (rman_get_bustag(r) == (void*)ARM_BUS_SPACE_MEM) {
caddr_t vaddr = 0;
u_int32_t paddr;
u_int32_t psize;
u_int32_t poffs;
paddr = rman_get_start(r);
psize = rman_get_size(r);
poffs = paddr - trunc_page(paddr);
vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
rman_set_virtual(r, vaddr);
rman_set_bushandle(r, (bus_space_handle_t) vaddr);
}
return (rman_activate_resource(r));
}
DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);

208
sys/arm/arm/nexus_io.c Normal file
View File

@ -0,0 +1,208 @@
/* $NetBSD: mainbus_io.c,v 1.13 2003/07/15 00:24:47 lukem Exp $ */
/*
* Copyright (c) 1997 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* bus_space I/O functions for mainbus
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>
#include <machine/bus.h>
#include <machine/pmap.h>
/* Proto types for all the bus_space structure functions */
vm_offset_t lala;
bs_protos(nexus);
/* Declare the mainbus bus space tag */
struct bus_space mainbus_bs_tag = {
/* cookie */
NULL,
/* mapping/unmapping */
nexus_bs_map,
nexus_bs_unmap,
nexus_bs_subregion,
/* allocation/deallocation */
nexus_bs_alloc,
nexus_bs_free,
/* get kernel virtual address */
0, /* there is no linear mapping */
NULL,
/* barrier */
nexus_bs_barrier,
/* read (single) */
nexus_bs_r_1,
nexus_bs_r_2,
nexus_bs_r_4,
NULL,
/* read multiple */
NULL,
nexus_bs_rm_2,
NULL,
NULL,
/* read region */
NULL,
NULL,
NULL,
NULL,
/* write (single) */
nexus_bs_w_1,
nexus_bs_w_2,
nexus_bs_w_4,
NULL,
/* write multiple */
nexus_bs_wm_1,
nexus_bs_wm_2,
NULL,
NULL,
/* write region */
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
/* set region */
NULL,
NULL,
NULL,
NULL,
/* copy */
NULL,
NULL,
NULL,
NULL,
};
/* bus space functions */
int
nexus_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int cacheable,
bus_space_handle_t *bshp)
{
return(0);
}
int
nexus_bs_alloc(t, rstart, rend, size, alignment, boundary, cacheable,
bpap, bshp)
void *t;
bus_addr_t rstart, rend;
bus_size_t size, alignment, boundary;
int cacheable;
bus_addr_t *bpap;
bus_space_handle_t *bshp;
{
panic("mainbus_bs_alloc(): Help!");
}
void
nexus_bs_unmap(void *t, bus_size_t size)
{
/*
* Temporary implementation
*/
}
void
nexus_bs_free(t, bsh, size)
void *t;
bus_space_handle_t bsh;
bus_size_t size;
{
panic("mainbus_bs_free(): Help!");
/* mainbus_bs_unmap() does all that we need to do. */
/* mainbus_bs_unmap(t, bsh, size);*/
}
int
nexus_bs_subregion(t, bsh, offset, size, nbshp)
void *t;
bus_space_handle_t bsh;
bus_size_t offset, size;
bus_space_handle_t *nbshp;
{
*nbshp = bsh + offset;
return (0);
}
int
nexus_bs_mmap(dev_t dev, vm_offset_t off, vm_paddr_t *addr, int prot)
{
*addr = off;
return (0);
}
void
nexus_bs_barrier(t, bsh, offset, len, flags)
void *t;
bus_space_handle_t bsh;
bus_size_t offset, len;
int flags;
{
}
/* End of mainbus_io.c */

114
sys/arm/arm/nexus_io_asm.S Normal file
View File

@ -0,0 +1,114 @@
/* $NetBSD: mainbus_io_asm.S,v 1.1 2001/02/24 19:38:02 reinoud Exp $ */
/*
* Copyright (c) 1997 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* bus_space I/O functions for nexus
*/
/*
* read single
*/
ENTRY(nexus_bs_r_1)
ldrb r0, [r1, r2, lsl #2]
mov pc, lr
ENTRY(nexus_bs_r_2)
ldr r0, [r1, r2, lsl #2]
bic r0, r0, #0xff000000
bic r0, r0, #0x00ff0000
mov pc, lr
ENTRY(nexus_bs_r_4)
ldr r0, [r1, r2, lsl #2]
mov pc, lr
/*
* write single
*/
ENTRY(nexus_bs_w_1)
strb r3, [r1, r2, lsl #2]
mov pc, lr
ENTRY(nexus_bs_w_2)
mov r3, r3, lsl #16
orr r3, r3, r3, lsr #16
str r3, [r1, r2, lsl #2]
mov pc, lr
ENTRY(nexus_bs_w_4)
str r3, [r1, r2, lsl #2]
mov pc, lr
/*
* read multiple
*/
ENTRY(nexus_bs_rm_2)
add r0, r1, r2, lsl #2
mov r1, r3
ldr r2, [sp, #0]
b _C_LABEL(insw16)
/*
* write multiple
*/
ENTRY(nexus_bs_wm_1)
add r0, r1, r2, lsl #2
ldr r2, [sp, #0]
/* Make sure that we have a positive length */
cmp r2, #0x00000000
movle pc, lr
nexus_wm_1_loop:
ldrb r1, [r3], #0x0001
str r1, [r0]
subs r2, r2, #0x00000001
bgt nexus_wm_1_loop
mov pc, lr
ENTRY(nexus_bs_wm_2)
add r0, r1, r2, lsl #2
mov r1, r3
ldr r2, [sp, #0]
b _C_LABEL(outsw16)

4650
sys/arm/arm/pmap.c Normal file

File diff suppressed because it is too large Load Diff

80
sys/arm/arm/setcpsr.S Normal file
View File

@ -0,0 +1,80 @@
/* $NetBSD: setcpsr.S,v 1.2 2002/08/15 01:37:02 briggs Exp $ */
/*
* Copyright (c) 1994 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* setcpsr.S
*
* Miscellaneous routines to play with the CPSR register
*
* Eventually this routine can be inline assembly.
*
* Created : 12/09/94
*
* Based of kate/display/setcpsr.s
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/* Sets and clears bits in the CPSR register
*
* r0 - bic mask
* r1 - eor mask
*/
ENTRY_NP(SetCPSR)
mrs r3, cpsr /* Set the CPSR */
bic r2, r3, r0
eor r2, r2, r1
msr cpsr_all, r2
mov r0, r3 /* Return the old CPSR */
mov pc, lr
/* Gets the CPSR register
*
* Returns the CPSR in r0
*/
ENTRY_NP(GetCPSR)
mrs r0, cpsr /* Get the CPSR */
mov pc, lr

94
sys/arm/arm/setstack.s Normal file
View File

@ -0,0 +1,94 @@
/* $NetBSD: setstack.S,v 1.1 2001/07/28 13:28:03 chris Exp $ */
/*
* Copyright (c) 1994 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* setstack.S
*
* Miscellaneous routine to play with the stack pointer in different CPU modes
*
* Eventually this routine can be inline assembly.
*
* Created : 17/09/94
*
* Based of kate/display/setstack.s
*
*/
#include <machine/armreg.h>
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/* To set the stack pointer for a particular mode we must switch
* to that mode update the banked r13 and then switch back.
* This routine provides an easy way of doing this for any mode
*
* r0 = CPU mode
* r1 = stackptr
*/
ENTRY(set_stackptr)
mrs r3, cpsr_all /* Switch to the appropriate mode */
bic r2, r3, #(PSR_MODE)
orr r2, r2, r0
msr cpsr_all, r2
mov sp, r1 /* Set the stack pointer */
msr cpsr_all, r3 /* Restore the old mode */
mov pc, lr /* Exit */
/* To get the stack pointer for a particular mode we must switch
* to that mode copy the banked r13 and then switch back.
* This routine provides an easy way of doing this for any mode
*
* r0 = CPU mode
*/
ENTRY(get_stackptr)
mrs r3, cpsr_all /* Switch to the appropriate mode */
bic r2, r3, #(PSR_MODE)
orr r2, r2, r0
msr cpsr_all, r2
mov r0, sp /* Set the stack pointer */
msr cpsr_all, r3 /* Restore the old mode */
mov pc, lr /* Exit */
/* End of setstack.S */

72
sys/arm/arm/support.S Normal file
View File

@ -0,0 +1,72 @@
/*-
* Copyright (c) 2004 Olivier Houchard
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <machine/asm.h>
#include <machine/asmacros.h>
__FBSDID("$FreeBSD$");
#include "assym.s"
ENTRY(casuptr)
mov r1, r2
bl suword
/*
* New experimental definitions of IRQdisable and IRQenable
* These keep FIQ's enabled since FIQ's are special.
*/
#define IRQdisable \
mrs r14, cpsr ; \
orr r14, r14, #(I32_bit) ; \
msr cpsr_c, r14 ; \
#define IRQenable \
mrs r14, cpsr ; \
bic r14, r14, #(I32_bit) ; \
msr cpsr_c, r14 ; \
/*
* These are used for switching the translation table/DACR.
* Since the vector page can be invalid for a short time, we must
* disable both regular IRQs *and* FIQs.
*
* XXX: This is not necessary if the vector table is relocated.
*/
#define IRQdisableALL \
mrs r14, cpsr ; \
orr r14, r14, #(I32_bit) ; \
msr cpsr_all, r14
#define IRQenableALL \
mrs r14, cpsr ; \
bic r14, r14, #(I32_bit) ; \
msr cpsr_all, r14
ENTRY(disable_intr)
IRQdisableALL
ENTRY(enable_intr)
IRQenableALL

543
sys/arm/arm/swtch.S Normal file
View File

@ -0,0 +1,543 @@
/* $NetBSD: cpuswitch.S,v 1.41 2003/11/15 08:44:18 scw Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Steve C. Woodford for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1994-1998 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* cpuswitch.S
*
* cpu switching functions
*
* Created : 15/10/94
*
*/
#include <machine/asm.h>
#include <machine/asmacros.h>
#include <machine/armreg.h>
__FBSDID("$FreeBSD$");
#include "assym.s"
/*
* New experimental definitions of IRQdisable and IRQenable
* These keep FIQ's enabled since FIQ's are special.
*/
#define DOMAIN_CLIENT 0x01
#define IRQdisable \
mrs r14, cpsr ; \
orr r14, r14, #(I32_bit) ; \
msr cpsr_c, r14 ; \
#define IRQenable \
mrs r14, cpsr ; \
bic r14, r14, #(I32_bit) ; \
msr cpsr_c, r14 ; \
/*
* These are used for switching the translation table/DACR.
* Since the vector page can be invalid for a short time, we must
* disable both regular IRQs *and* FIQs.
*
* XXX: This is not necessary if the vector table is relocated.
*/
#define IRQdisableALL \
mrs r14, cpsr ; \
orr r14, r14, #(I32_bit | F32_bit) ; \
msr cpsr_c, r14
#define IRQenableALL \
mrs r14, cpsr ; \
bic r14, r14, #(I32_bit | F32_bit) ; \
msr cpsr_c, r14
.Lpcpu:
.word _C_LABEL(__pcpu)
.Lcurthread:
.word _C_LABEL(__pcpu) + PC_CURTHREAD
.Lcurpcb:
.word _C_LABEL(__pcpu) + PC_CURPCB
.Lcpufuncs:
.word _C_LABEL(cpufuncs)
.Lblock_userspace_access:
.word _C_LABEL(block_userspace_access)
.Lcpu_do_powersave:
.word _C_LABEL(cpu_do_powersave)
.Lpmap_kernel_cstate:
.word (kernel_pmap_store + PMAP_CSTATE)
.Llast_cache_state_ptr:
.word _C_LABEL(pmap_cache_state)
/* XXX: wow */
ENTRY(cpu_throw)
ENTRY(cpu_switch)
stmfd sp!, {r4-r7, lr}
mov r6, r1
mov r1, r0
.Lswitch_resume:
/* rem: r1 = old lwp */
/* rem: r4 = return value [not used if came from cpu_switchto()] */
/* rem: r6 = new process */
/* rem: interrupts are disabled */
#ifdef MULTIPROCESSOR
/* XXX use curcpu() */
ldr r0, .Lcpu_info_store
str r0, [r6, #(L_CPU)]
#else
/* l->l_cpu initialized in fork1() for single-processor */
#endif
/* Process is now on a processor. */
/* We have a new curlwp now so make a note it */
ldr r7, .Lcurthread
str r6, [r7]
/* Hook in a new pcb */
ldr r7, .Lcurpcb
ldr r0, [r6, #(TD_PCB)]
str r0, [r7]
/* At this point we can allow IRQ's again. */
/* rem: r1 = old lwp */
/* rem: r4 = return value */
/* rem: r6 = new process */
/* rem: interrupts are enabled */
/* Remember the old lwp in r0 */
mov r0, r1
/*
* If the old lwp on entry to cpu_switch was zero then the
* process that called it was exiting. This means that we do
* not need to save the current context. Instead we can jump
* straight to restoring the context for the new process.
*/
teq r0, #0x00000000
beq .Lswitch_exited
/* rem: r0 = old lwp */
/* rem: r4 = return value */
/* rem: r6 = new process */
/* rem: interrupts are enabled */
/* Stage two : Save old context */
/* Get the user structure for the old lwp. */
ldr r1, [r0, #(TD_PCB)]
/* Save all the registers in the old lwp's pcb */
#ifndef __XSCALE__
add r7, r1, #(PCB_R8)
stmia r7, {r8-r13}
#else
strd r8, [r1, #(PCB_R8)]
strd r10, [r1, #(PCB_R10)]
strd r12, [r1, #(PCB_R12)]
#endif
/*
* NOTE: We can now use r8-r13 until it is time to restore
* them for the new process.
*/
/* Remember the old PCB. */
mov r8, r1
/* r1 now free! */
/* Get the user structure for the new process in r9 */
ldr r9, [r6, #(TD_PCB)]
/*
* This can be optimised... We know we want to go from SVC32
* mode to UND32 mode
*/
mrs r3, cpsr
bic r2, r3, #(PSR_MODE)
orr r2, r2, #(PSR_UND32_MODE | I32_bit)
msr cpsr_c, r2
str sp, [r8, #(PCB_UND_SP)]
msr cpsr_c, r3 /* Restore the old mode */
/* rem: r0 = old lwp */
/* rem: r4 = return value */
/* rem: r6 = new process */
/* rem: r8 = old PCB */
/* rem: r9 = new PCB */
/* rem: interrupts are enabled */
/* What else needs to be saved Only FPA stuff when that is supported */
/* Third phase : restore saved context */
/* rem: r0 = old lwp */
/* rem: r4 = return value */
/* rem: r6 = new lwp */
/* rem: r8 = old PCB */
/* rem: r9 = new PCB */
/* rem: interrupts are enabled */
/*
* Get the new L1 table pointer into r11. If we're switching to
* an LWP with the same address space as the outgoing one, we can
* skip the cache purge and the TTB load.
*
* To avoid data dep stalls that would happen anyway, we try
* and get some useful work done in the mean time.
*/
ldr r10, [r8, #(PCB_PAGEDIR)] /* r10 = old L1 */
ldr r11, [r9, #(PCB_PAGEDIR)] /* r11 = new L1 */
ldr r0, [r8, #(PCB_DACR)] /* r0 = old DACR */
ldr r1, [r9, #(PCB_DACR)] /* r1 = new DACR */
ldr r8, [r9, #(PCB_CSTATE)] /* r8 = &new_pmap->pm_cstate */
ldr r5, .Llast_cache_state_ptr /* Previous thread's cstate */
teq r10, r11 /* Same L1? */
ldr r5, [r5]
cmpeq r0, r1 /* Same DACR? */
beq .Lcs_context_switched /* yes! */
ldr r3, .Lblock_userspace_access
mov r12, #0
cmp r5, #0 /* No last vm? (switch_exit) */
beq .Lcs_cache_purge_skipped /* No, we can skip cache flsh */
mov r2, #DOMAIN_CLIENT
cmp r1, r2, lsl #(PMAP_DOMAIN_KERNEL * 2) /* Sw to kernel thread? */
beq .Lcs_cache_purge_skipped /* Yup. Don't flush cache */
cmp r5, r8 /* Same userland VM space? */
ldrneb r12, [r5, #(CS_CACHE_ID)] /* Last VM space cache state */
/*
* We're definately switching to a new userland VM space,
* and the previous userland VM space has yet to be flushed
* from the cache/tlb.
*
* r12 holds the previous VM space's cs_cache_id state
*/
tst r12, #0xff /* Test cs_cache_id */
beq .Lcs_cache_purge_skipped /* VM space is not in cache */
/*
* Definately need to flush the cache.
* Mark the old VM space as NOT being resident in the cache.
*/
mov r2, #0x00000000
strb r2, [r5, #(CS_CACHE_ID)]
strb r2, [r5, #(CS_CACHE_D)]
/*
* Don't allow user space access between the purge and the switch.
*/
mov r2, #0x00000001
str r2, [r3]
stmfd sp!, {r0-r3}
ldr r1, .Lcpufuncs
mov lr, pc
ldr pc, [r1, #CF_IDCACHE_WBINV_ALL]
ldmfd sp!, {r0-r3}
.Lcs_cache_purge_skipped:
/* rem: r1 = new DACR */
/* rem: r3 = &block_userspace_access */
/* rem: r4 = return value */
/* rem: r5 = &old_pmap->pm_cstate (or NULL) */
/* rem: r6 = new lwp */
/* rem: r8 = &new_pmap->pm_cstate */
/* rem: r9 = new PCB */
/* rem: r10 = old L1 */
/* rem: r11 = new L1 */
mov r2, #0x00000000
ldr r7, [r9, #(PCB_PL1VEC)]
/*
* At this point we need to kill IRQ's again.
*
* XXXSCW: Don't need to block FIQs if vectors have been relocated
*/
#if 0
IRQdisableALL
#endif
/*
* Interrupts are disabled so we can allow user space accesses again
* as none will occur until interrupts are re-enabled after the
* switch.
*/
str r2, [r3]
/*
* Ensure the vector table is accessible by fixing up the L1
*/
cmp r7, #0 /* No need to fixup vector table? */
ldrne r2, [r7] /* But if yes, fetch current value */
ldrne r0, [r9, #(PCB_L1VEC)] /* Fetch new vector_page value */
mcr p15, 0, r1, c3, c0, 0 /* Update DACR for new context */
cmpne r2, r0 /* Stuffing the same value? */
#if 0
strne r0, [r7] /* Nope, update it */
#else
beq .Lcs_same_vector
str r0, [r7] /* Otherwise, update it */
/*
* Need to sync the cache to make sure that last store is
* visible to the MMU.
*/
ldr r2, .Lcpufuncs
mov r0, r7
mov r1, #4
mov lr, pc
ldr pc, [r2, #CF_DCACHE_WB_RANGE]
.Lcs_same_vector:
#endif /* PMAP_INCLUDE_PTE_SYNC */
cmp r10, r11 /* Switching to the same L1? */
ldr r10, .Lcpufuncs
beq .Lcs_same_l1 /* Yup. */
/*
* Do a full context switch, including full TLB flush.
*/
mov r0, r11
mov lr, pc
ldr pc, [r10, #CF_CONTEXT_SWITCH]
/*
* Mark the old VM space as NOT being resident in the TLB
*/
mov r2, #0x00000000
cmp r5, #0
strneh r2, [r5, #(CS_TLB_ID)]
b .Lcs_context_switched
/*
* We're switching to a different process in the same L1.
* In this situation, we only need to flush the TLB for the
* vector_page mapping, and even then only if r7 is non-NULL.
*/
.Lcs_same_l1:
cmp r7, #0
movne r0, #0 /* We *know* vector_page's VA is 0x0 */
movne lr, pc
ldrne pc, [r10, #CF_TLB_FLUSHID_SE]
.Lcs_context_switched:
/* rem: r8 = &new_pmap->pm_cstate */
/* XXXSCW: Safe to re-enable FIQs here */
/*
* The new VM space is live in the cache and TLB.
* Update its cache/tlb state, and if it's not the kernel
* pmap, update the 'last cache state' pointer.
*/
mov r2, #-1
ldr r5, .Lpmap_kernel_cstate
ldr r0, .Llast_cache_state_ptr
str r2, [r8, #(CS_ALL)]
cmp r5, r8
strne r8, [r0]
/* rem: r4 = return value */
/* rem: r6 = new lwp */
/* rem: r9 = new PCB */
/*
* This can be optimised... We know we want to go from SVC32
* mode to UND32 mode
*/
mrs r3, cpsr
bic r2, r3, #(PSR_MODE)
orr r2, r2, #(PSR_UND32_MODE)
msr cpsr_c, r2
ldr sp, [r9, #(PCB_UND_SP)]
msr cpsr_c, r3 /* Restore the old mode */
/* Restore all the save registers */
#ifndef __XSCALE__
add r7, r9, #PCB_R8
ldmia r7, {r8-r13}
sub r7, r7, #PCB_R8 /* restore PCB pointer */
#else
mov r7, r9
ldr r8, [r7, #(PCB_R8)]
ldr r9, [r7, #(PCB_R9)]
ldr r10, [r7, #(PCB_R10)]
ldr r11, [r7, #(PCB_R11)]
ldr r12, [r7, #(PCB_R12)]
ldr r13, [r7, #(PCB_SP)]
#endif
ldr r5, [r6, #(TD_PROC)] /* fetch the proc for below */
/* rem: r4 = return value */
/* rem: r5 = new lwp's proc */
/* rem: r6 = new lwp */
/* rem: r7 = new pcb */
#ifdef ARMFPE
add r0, r7, #(USER_SIZE) & 0x00ff
add r0, r0, #(USER_SIZE) & 0xff00
bl _C_LABEL(arm_fpe_core_changecontext)
#endif
/* We can enable interrupts again */
#if 0
IRQenableALL
#endif
/* rem: r4 = return value */
/* rem: r5 = new lwp's proc */
/* rem: r6 = new lwp */
/* rem: r7 = new PCB */
.Lswitch_return:
/*
* Pull the registers that got pushed when either savectx() or
* cpu_switch() was called and return.
*/
ldmfd sp!, {r4-r7, pc}
.Lswitch_exited:
/*
* We skip the cache purge because switch_exit() already did it.
* Load up registers the way .Lcs_cache_purge_skipped expects.
* Userpsace access already blocked by switch_exit().
*/
ldr r9, [r6, #(TD_PCB)] /* r9 = new PCB */
ldr r3, .Lblock_userspace_access
mrc p15, 0, r10, c2, c0, 0 /* r10 = old L1 */
mov r5, #0 /* No previous cache state */
ldr r1, [r9, #(PCB_DACR)] /* r1 = new DACR */
ldr r8, [r9, #(PCB_CSTATE)] /* r8 = new cache state */
ldr r11, [r9, #(PCB_PAGEDIR)] /* r11 = new L1 */
b .Lcs_cache_purge_skipped
#ifdef DIAGNOSTIC
.Lswitch_bogons:
adr r0, .Lswitch_panic_str
bl _C_LABEL(panic)
1: nop
b 1b
.Lswitch_panic_str:
.asciz "cpu_switch: sched_qs empty with non-zero sched_whichqs!\n"
#endif
ENTRY(savectx)
mov pc, lr
ENTRY(fork_trampoline)
mov r1, r5
mov r2, sp
mov r0, r4
mov lr, pc
#if 0
mov r2, sp
#endif
#if 0
mov pc, r4
#endif
bl _C_LABEL(fork_exit)
/* Kill irq's */
mrs r0, cpsr
orr r0, r0, #(I32_bit)
msr cpsr_c, r0
PULLFRAME
movs pc, lr /* Exit */
#ifndef __XSCALE__
.type .Lcpu_switch_ffs_table, _ASM_TYPE_OBJECT;
.Lcpu_switch_ffs_table:
/* same as ffs table but all nums are -1 from that */
/* 0 1 2 3 4 5 6 7 */
.byte 0, 0, 1, 12, 2, 6, 0, 13 /* 0- 7 */
.byte 3, 0, 7, 0, 0, 0, 0, 14 /* 8-15 */
.byte 10, 4, 0, 0, 8, 0, 0, 25 /* 16-23 */
.byte 0, 0, 0, 0, 0, 21, 27, 15 /* 24-31 */
.byte 31, 11, 5, 0, 0, 0, 0, 0 /* 32-39 */
.byte 9, 0, 0, 24, 0, 0, 20, 26 /* 40-47 */
.byte 30, 0, 0, 0, 0, 23, 0, 19 /* 48-55 */
.byte 29, 0, 22, 18, 28, 17, 16, 0 /* 56-63 */
#endif /* !__XSCALE_ */

69
sys/arm/arm/sys_machdep.c Normal file
View File

@ -0,0 +1,69 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_kstack_pages.h"
#include "opt_mac.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/lock.h>
#include <sys/mac.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/smp.h>
#include <sys/sysproto.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <sys/sysent.h>
#ifndef _SYS_SYSPROTO_H_
struct sysarch_args {
int op;
char *parms;
};
#endif
int
sysarch(td, uap)
struct thread *td;
register struct sysarch_args *uap;
{
return (0);
}

917
sys/arm/arm/trap.c Normal file
View File

@ -0,0 +1,917 @@
/* $NetBSD: fault.c,v 1.45 2003/11/20 14:44:36 scw Exp $ */
/*
* Copyright 2004 Olivier Houchard
* Copyright 2003 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Steve C. Woodford for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1994-1997 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* fault.c
*
* Fault handlers
*
* Created : 28/11/94
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/syscall.h>
#include <sys/sysent.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_kern.h>
#include <vm/vm_map.h>
#include <vm/vm_extern.h>
#include <machine/cpuconf.h>
#include <machine/vmparam.h>
#include <machine/frame.h>
#include <machine/katelib.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/proc.h>
#include <machine/swi.h>
#if !defined(DDB)
#define kdb_trap kgdb_trap
#endif
void swi_handler(trapframe_t *);
void undefinedinstruction(trapframe_t *);
#include <machine/disassem.h>
#include <machine/machdep.h>
extern char fusubailout[];
#ifdef DEBUG
int last_fault_code; /* For the benefit of pmap_fault_fixup() */
#endif
#if defined(CPU_ARM3) || defined(CPU_ARM6) || \
defined(CPU_ARM7) || defined(CPU_ARM7TDMI)
/* These CPUs may need data/prefetch abort fixups */
#define CPU_ABORT_FIXUP_REQUIRED
#endif
struct ksig {
int signb;
u_long code;
};
struct data_abort {
int (*func)(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
const char *desc;
};
static int dab_fatal(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
static int dab_align(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
static int dab_buserr(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
static const struct data_abort data_aborts[] = {
{dab_fatal, "Vector Exception"},
{dab_align, "Alignment Fault 1"},
{dab_fatal, "Terminal Exception"},
{dab_align, "Alignment Fault 3"},
{dab_buserr, "External Linefetch Abort (S)"},
{NULL, "Translation Fault (S)"},
{dab_buserr, "External Linefetch Abort (P)"},
{NULL, "Translation Fault (P)"},
{dab_buserr, "External Non-Linefetch Abort (S)"},
{NULL, "Domain Fault (S)"},
{dab_buserr, "External Non-Linefetch Abort (P)"},
{NULL, "Domain Fault (P)"},
{dab_buserr, "External Translation Abort (L1)"},
{NULL, "Permission Fault (S)"},
{dab_buserr, "External Translation Abort (L2)"},
{NULL, "Permission Fault (P)"}
};
/* Determine if a fault came from user mode */
#define TRAP_USERMODE(tf) ((tf->tf_spsr & PSR_MODE) == PSR_USR32_MODE)
/* Determine if 'x' is a permission fault */
#define IS_PERMISSION_FAULT(x) \
(((1 << ((x) & FAULT_TYPE_MASK)) & \
((1 << FAULT_PERM_P) | (1 << FAULT_PERM_S))) != 0)
static __inline void
call_trapsignal(struct thread *td, int sig, u_long code)
{
trapsignal(td, sig, code);
}
static __inline int
data_abort_fixup(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
{
#ifdef CPU_ABORT_FIXUP_REQUIRED
int error;
/* Call the cpu specific data abort fixup routine */
error = cpu_dataabt_fixup(tf);
if (__predict_true(error != ABORT_FIXUP_FAILED))
return (error);
/*
* Oops, couldn't fix up the instruction
*/
printf("data_abort_fixup: fixup for %s mode data abort failed.\n",
TRAP_USERMODE(tf) ? "user" : "kernel");
printf("pc = 0x%08x, opcode 0x%08x, insn = ", tf->tf_pc,
*((u_int *)tf->tf_pc));
disassemble(tf->tf_pc);
/* Die now if this happened in kernel mode */
if (!TRAP_USERMODE(tf))
dab_fatal(tf, fsr, far, td, NULL, ksig);
return (error);
#else
return (ABORT_FIXUP_OK);
#endif /* CPU_ABORT_FIXUP_REQUIRED */
}
extern int curpid;
void
data_abort_handler(trapframe_t *tf)
{
struct vm_map *map;
struct pcb *pcb;
struct thread *td;
u_int user, far, fsr;
vm_prot_t ftype;
void *onfault;
vm_offset_t va;
u_int sticks = 0;
int error = 0;
struct ksig ksig;
/* Grab FAR/FSR before enabling interrupts */
far = cpu_faultaddress();
fsr = cpu_faultstatus();
#if 0
/* Update vmmeter statistics */
vmexp.traps++;
#endif
/* Re-enable interrupts if they were enabled previously */
if (__predict_true((tf->tf_spsr & I32_bit) == 0))
enable_interrupts(I32_bit);
/* Get the current lwp structure or lwp0 if there is none */
td = (curthread != NULL) ? curthread : &thread0;
/* Data abort came from user mode? */
user = TRAP_USERMODE(tf);
/* Grab the current pcb */
pcb = td->td_pcb;
/* Invoke the appropriate handler, if necessary */
if (__predict_false(data_aborts[fsr & FAULT_TYPE_MASK].func != NULL)) {
if ((data_aborts[fsr & FAULT_TYPE_MASK].func)(tf, fsr, far,
td, &ksig))
goto do_trapsignal;
goto out;
}
/*
* At this point, we're dealing with one of the following data aborts:
*
* FAULT_TRANS_S - Translation -- Section
* FAULT_TRANS_P - Translation -- Page
* FAULT_DOMAIN_S - Domain -- Section
* FAULT_DOMAIN_P - Domain -- Page
* FAULT_PERM_S - Permission -- Section
* FAULT_PERM_P - Permission -- Page
*
* These are the main virtual memory-related faults signalled by
* the MMU.
*/
/* fusubailout is used by [fs]uswintr to avoid page faulting */
if (__predict_false(pcb->pcb_onfault == fusubailout)) {
tf->tf_r0 = EFAULT;
tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
return;
}
if (user) {
sticks = td->td_sticks;
td->td_frame = tf;
}
/*
* Make sure the Program Counter is sane. We could fall foul of
* someone executing Thumb code, in which case the PC might not
* be word-aligned. This would cause a kernel alignment fault
* further down if we have to decode the current instruction.
* XXX: It would be nice to be able to support Thumb at some point.
*/
if (__predict_false((tf->tf_pc & 3) != 0)) {
if (user) {
/*
* Give the user an illegal instruction signal.
*/
/* Deliver a SIGILL to the process */
ksig.signb = SIGILL;
ksig.code = 0;
goto do_trapsignal;
}
/*
* The kernel never executes Thumb code.
*/
printf("\ndata_abort_fault: Misaligned Kernel-mode "
"Program Counter\n");
dab_fatal(tf, fsr, far, td, &ksig);
}
/* See if the cpu state needs to be fixed up */
switch (data_abort_fixup(tf, fsr, far, td, &ksig)) {
case ABORT_FIXUP_RETURN:
return;
case ABORT_FIXUP_FAILED:
/* Deliver a SIGILL to the process */
ksig.signb = SIGILL;
ksig.code = 0;
goto do_trapsignal;
default:
break;
}
va = trunc_page((vm_offset_t)far);
/*
* It is only a kernel address space fault iff:
* 1. user == 0 and
* 2. pcb_onfault not set or
* 3. pcb_onfault set and not LDRT/LDRBT/STRT/STRBT instruction.
*/
if (user == 0 && (va >= VM_MIN_KERNEL_ADDRESS ||
(va < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW)) &&
__predict_true((pcb->pcb_onfault == NULL ||
(ReadWord(tf->tf_pc) & 0x05200000) != 0x04200000))) {
map = kernel_map;
/* Was the fault due to the FPE/IPKDB ? */
if (__predict_false((tf->tf_spsr & PSR_MODE)==PSR_UND32_MODE)) {
/*
* Force exit via userret()
* This is necessary as the FPE is an extension to
* userland that actually runs in a priveledged mode
* but uses USR mode permissions for its accesses.
*/
user = 1;
ksig.signb = SIGSEGV;
ksig.code = 0;
goto do_trapsignal;
}
} else {
map = &td->td_proc->p_vmspace->vm_map;
}
/*
* We need to know whether the page should be mapped
* as R or R/W. The MMU does not give us the info as
* to whether the fault was caused by a read or a write.
*
* However, we know that a permission fault can only be
* the result of a write to a read-only location, so
* we can deal with those quickly.
*
* Otherwise we need to disassemble the instruction
* responsible to determine if it was a write.
*/
if (IS_PERMISSION_FAULT(fsr)) {
ftype = VM_PROT_WRITE;
} else {
u_int insn = ReadWord(tf->tf_pc);
if (((insn & 0x0c100000) == 0x04000000) || /* STR/STRB */
((insn & 0x0e1000b0) == 0x000000b0) || /* STRH/STRD */
((insn & 0x0a100000) == 0x08000000)) /* STM/CDT */
{
ftype = VM_PROT_WRITE;
}
else
if ((insn & 0x0fb00ff0) == 0x01000090) /* SWP */
ftype = VM_PROT_READ | VM_PROT_WRITE;
else
ftype = VM_PROT_READ;
}
/*
* See if the fault is as a result of ref/mod emulation,
* or domain mismatch.
*/
#ifdef DEBUG
last_fault_code = fsr;
#endif
if (pmap_fault_fixup(map->pmap, va, ftype, user)) {
goto out;
}
onfault = pcb->pcb_onfault;
pcb->pcb_onfault = NULL;
error = vm_fault(map, va, ftype, (ftype & VM_PROT_WRITE) ?
VM_FAULT_DIRTY : VM_FAULT_NORMAL);
pcb->pcb_onfault = onfault;
if (__predict_true(error == 0)) {
goto out;
}
if (user == 0) {
if (pcb->pcb_onfault) {
tf->tf_r0 = error;
tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
return;
}
printf("\nvm_fault(%p, %x, %x, 0) -> %x\n", map, va, ftype,
error);
dab_fatal(tf, fsr, far, td, &ksig);
}
if (error == ENOMEM) {
printf("VM: pid %d (%s), uid %d killed: "
"out of swap\n", td->td_proc->p_pid, td->td_proc->p_comm,
(td->td_proc->p_ucred) ?
td->td_proc->p_ucred->cr_uid : -1);
ksig.signb = SIGKILL;
} else {
ksig.signb = SIGSEGV;
}
ksig.code = 0;
do_trapsignal:
call_trapsignal(td, ksig.signb, ksig.code);
out:
/* If returning to user mode, make sure to invoke userret() */
if (user)
userret(td, tf, sticks);
}
/*
* dab_fatal() handles the following data aborts:
*
* FAULT_WRTBUF_0 - Vector Exception
* FAULT_WRTBUF_1 - Terminal Exception
*
* We should never see these on a properly functioning system.
*
* This function is also called by the other handlers if they
* detect a fatal problem.
*
* Note: If 'l' is NULL, we assume we're dealing with a prefetch abort.
*/
static int
dab_fatal(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
{
const char *mode;
mode = TRAP_USERMODE(tf) ? "user" : "kernel";
if (td != NULL) {
printf("Fatal %s mode data abort: '%s'\n", mode,
data_aborts[fsr & FAULT_TYPE_MASK].desc);
printf("trapframe: %p\nFSR=%08x, FAR=", tf, fsr);
if ((fsr & FAULT_IMPRECISE) == 0)
printf("%08x, ", far);
else
printf("Invalid, ");
printf("spsr=%08x\n", tf->tf_spsr);
} else {
printf("Fatal %s mode prefetch abort at 0x%08x\n",
mode, tf->tf_pc);
printf("trapframe: %p, spsr=%08x\n", tf, tf->tf_spsr);
}
printf("r0 =%08x, r1 =%08x, r2 =%08x, r3 =%08x\n",
tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3);
printf("r4 =%08x, r5 =%08x, r6 =%08x, r7 =%08x\n",
tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7);
printf("r8 =%08x, r9 =%08x, r10=%08x, r11=%08x\n",
tf->tf_r8, tf->tf_r9, tf->tf_r10, tf->tf_r11);
printf("r12=%08x, ", tf->tf_r12);
if (TRAP_USERMODE(tf))
printf("usp=%08x, ulr=%08x",
tf->tf_usr_sp, tf->tf_usr_lr);
else
printf("ssp=%08x, slr=%08x",
tf->tf_svc_sp, tf->tf_svc_lr);
printf(", pc =%08x\n\n", tf->tf_pc);
#if defined(DDB) || defined(KGDB)
kdb_trap(T_FAULT, tf);
#endif
panic("Fatal abort");
/*NOTREACHED*/
}
/*
* dab_align() handles the following data aborts:
*
* FAULT_ALIGN_0 - Alignment fault
* FAULT_ALIGN_0 - Alignment fault
*
* These faults are fatal if they happen in kernel mode. Otherwise, we
* deliver a bus error to the process.
*/
static int
dab_align(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
{
/* Alignment faults are always fatal if they occur in kernel mode */
if (!TRAP_USERMODE(tf))
dab_fatal(tf, fsr, far, td, ksig);
/* pcb_onfault *must* be NULL at this point */
/* See if the cpu state needs to be fixed up */
(void) data_abort_fixup(tf, fsr, far, td, ksig);
/* Deliver a bus error signal to the process */
ksig->code = 0;
ksig->signb = SIGBUS;
td->td_frame = tf;
return (1);
}
/*
* dab_buserr() handles the following data aborts:
*
* FAULT_BUSERR_0 - External Abort on Linefetch -- Section
* FAULT_BUSERR_1 - External Abort on Linefetch -- Page
* FAULT_BUSERR_2 - External Abort on Non-linefetch -- Section
* FAULT_BUSERR_3 - External Abort on Non-linefetch -- Page
* FAULT_BUSTRNL1 - External abort on Translation -- Level 1
* FAULT_BUSTRNL2 - External abort on Translation -- Level 2
*
* If pcb_onfault is set, flag the fault and return to the handler.
* If the fault occurred in user mode, give the process a SIGBUS.
*
* Note: On XScale, FAULT_BUSERR_0, FAULT_BUSERR_1, and FAULT_BUSERR_2
* can be flagged as imprecise in the FSR. This causes a real headache
* since some of the machine state is lost. In this case, tf->tf_pc
* may not actually point to the offending instruction. In fact, if
* we've taken a double abort fault, it generally points somewhere near
* the top of "data_abort_entry" in exception.S.
*
* In all other cases, these data aborts are considered fatal.
*/
static int
dab_buserr(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
{
struct pcb *pcb = td->td_pcb;
#ifdef __XSCALE__
if ((fsr & FAULT_IMPRECISE) != 0 &&
(tf->tf_spsr & PSR_MODE) == PSR_ABT32_MODE) {
/*
* Oops, an imprecise, double abort fault. We've lost the
* r14_abt/spsr_abt values corresponding to the original
* abort, and the spsr saved in the trapframe indicates
* ABT mode.
*/
tf->tf_spsr &= ~PSR_MODE;
/*
* We use a simple heuristic to determine if the double abort
* happened as a result of a kernel or user mode access.
* If the current trapframe is at the top of the kernel stack,
* the fault _must_ have come from user mode.
*/
if (tf != ((trapframe_t *)pcb->un_32.pcb32_sp) - 1) {
/*
* Kernel mode. We're either about to die a
* spectacular death, or pcb_onfault will come
* to our rescue. Either way, the current value
* of tf->tf_pc is irrelevant.
*/
tf->tf_spsr |= PSR_SVC32_MODE;
if (pcb->pcb_onfault == NULL)
printf("\nKernel mode double abort!\n");
} else {
/*
* User mode. We've lost the program counter at the
* time of the fault (not that it was accurate anyway;
* it's not called an imprecise fault for nothing).
* About all we can do is copy r14_usr to tf_pc and
* hope for the best. The process is about to get a
* SIGBUS, so it's probably history anyway.
*/
tf->tf_spsr |= PSR_USR32_MODE;
tf->tf_pc = tf->tf_usr_lr;
}
}
/* FAR is invalid for imprecise exceptions */
if ((fsr & FAULT_IMPRECISE) != 0)
far = 0;
#endif /* __XSCALE__ */
if (pcb->pcb_onfault) {
tf->tf_r0 = EFAULT;
tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
return (0);
}
/* See if the cpu state needs to be fixed up */
(void) data_abort_fixup(tf, fsr, far, td, ksig);
/*
* At this point, if the fault happened in kernel mode, we're toast
*/
if (!TRAP_USERMODE(tf))
dab_fatal(tf, fsr, far, td, ksig);
/* Deliver a bus error signal to the process */
ksig->signb = SIGBUS;
ksig->code = 0;
td->td_frame = tf;
return (1);
}
static __inline int
prefetch_abort_fixup(trapframe_t *tf, struct ksig *ksig)
{
#ifdef CPU_ABORT_FIXUP_REQUIRED
int error;
/* Call the cpu specific prefetch abort fixup routine */
error = cpu_prefetchabt_fixup(tf);
if (__predict_true(error != ABORT_FIXUP_FAILED))
return (error);
/*
* Oops, couldn't fix up the instruction
*/
printf(
"prefetch_abort_fixup: fixup for %s mode prefetch abort failed.\n",
TRAP_USERMODE(tf) ? "user" : "kernel");
printf("pc = 0x%08x, opcode 0x%08x, insn = ", tf->tf_pc,
*((u_int *)tf->tf_pc));
disassemble(tf->tf_pc);
/* Die now if this happened in kernel mode */
if (!TRAP_USERMODE(tf))
dab_fatal(tf, 0, tf->tf_pc, NULL, ksig);
return (error);
#else
return (ABORT_FIXUP_OK);
#endif /* CPU_ABORT_FIXUP_REQUIRED */
}
/*
* void prefetch_abort_handler(trapframe_t *tf)
*
* Abort handler called when instruction execution occurs at
* a non existent or restricted (access permissions) memory page.
* If the address is invalid and we were in SVC mode then panic as
* the kernel should never prefetch abort.
* If the address is invalid and the page is mapped then the user process
* does no have read permission so send it a signal.
* Otherwise fault the page in and try again.
*/
void
prefetch_abort_handler(trapframe_t *tf)
{
struct thread *td;
struct vm_map *map;
vm_offset_t fault_pc, va;
int error = 0;
u_int sticks = 0;
struct ksig ksig;
#if 0
/* Update vmmeter statistics */
uvmexp.traps++;
#endif
/*
* Enable IRQ's (disabled by the abort) This always comes
* from user mode so we know interrupts were not disabled.
* But we check anyway.
*/
if (__predict_true((tf->tf_spsr & I32_bit) == 0))
enable_interrupts(I32_bit);
/* See if the cpu state needs to be fixed up */
switch (prefetch_abort_fixup(tf, &ksig)) {
case ABORT_FIXUP_RETURN:
return;
case ABORT_FIXUP_FAILED:
/* Deliver a SIGILL to the process */
ksig.signb = SIGILL;
ksig.code = 0;
td = curthread;
td->td_frame = tf;
goto do_trapsignal;
default:
break;
}
/* Prefetch aborts cannot happen in kernel mode */
if (__predict_false(!TRAP_USERMODE(tf)))
dab_fatal(tf, 0, tf->tf_pc, NULL, &ksig);
/* Get fault address */
fault_pc = tf->tf_pc;
td = curthread;
td->td_frame = tf;
sticks = td->td_sticks;
/* Ok validate the address, can only execute in USER space */
if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS ||
(fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) {
ksig.signb = SIGSEGV;
ksig.code = 0;
goto do_trapsignal;
}
map = &td->td_proc->p_vmspace->vm_map;
va = trunc_page(fault_pc);
/*
* See if the pmap can handle this fault on its own...
*/
#ifdef DEBUG
last_fault_code = -1;
#endif
if (pmap_fault_fixup(map->pmap, va, VM_PROT_READ, 1))
goto out;
error = vm_fault(map, va, VM_PROT_READ /*| VM_PROT_EXECUTE*/,
VM_FAULT_NORMAL);
if (__predict_true(error == 0))
goto out;
if (error == ENOMEM) {
printf("VM: pid %d (%s), uid %d killed: "
"out of swap\n", td->td_proc->p_pid, td->td_proc->p_comm,
(td->td_proc->p_ucred) ?
td->td_proc->p_ucred->cr_uid : -1);
ksig.signb = SIGKILL;
} else {
ksig.signb = SIGSEGV;
}
ksig.code = 0;
do_trapsignal:
call_trapsignal(td, ksig.signb, ksig.code);
out:
userret(td, tf, sticks);
}
extern int badaddr_read_1(const uint8_t *, uint8_t *);
extern int badaddr_read_2(const uint16_t *, uint16_t *);
extern int badaddr_read_4(const uint32_t *, uint32_t *);
/*
* Tentatively read an 8, 16, or 32-bit value from 'addr'.
* If the read succeeds, the value is written to 'rptr' and zero is returned.
* Else, return EFAULT.
*/
int
badaddr_read(void *addr, size_t size, void *rptr)
{
union {
uint8_t v1;
uint16_t v2;
uint32_t v4;
} u;
int rv;
cpu_drain_writebuf();
/* Read from the test address. */
switch (size) {
case sizeof(uint8_t):
rv = badaddr_read_1(addr, &u.v1);
if (rv == 0 && rptr)
*(uint8_t *) rptr = u.v1;
break;
case sizeof(uint16_t):
rv = badaddr_read_2(addr, &u.v2);
if (rv == 0 && rptr)
*(uint16_t *) rptr = u.v2;
break;
case sizeof(uint32_t):
rv = badaddr_read_4(addr, &u.v4);
if (rv == 0 && rptr)
*(uint32_t *) rptr = u.v4;
break;
default:
panic("badaddr: invalid size (%lu)", (u_long) size);
}
/* Return EFAULT if the address was invalid, else zero */
return (rv);
}
#define MAXARGS 8
static void
syscall(struct thread *td, trapframe_t *frame, u_int32_t insn)
{
struct proc *p = td->td_proc;
int code, error;
u_int nap, nargs;
register_t *ap, *args, copyargs[MAXARGS];
struct sysent *callp;
int locked = 0;
switch (insn & SWI_OS_MASK) {
case 0: /* XXX: we need our own one. */
nap = 4;
break;
default:
trapsignal(td, SIGILL, 0);
userret(td, frame, td->td_sticks);
return;
}
code = insn & 0x000fffff;
ap = &frame->tf_r0;
if (code == SYS_syscall) {
code = *ap++;
nap--;
} else if (code == SYS___syscall) {
code = *ap++;
nap -= 2;
ap++;
}
if (p->p_sysent->sv_mask)
code &= p->p_sysent->sv_mask;
if (code >= p->p_sysent->sv_size)
callp = &p->p_sysent->sv_table[0];
else
callp = &p->p_sysent->sv_table[code];
nargs = callp->sy_narg & SYF_ARGMASK;
if (nargs <= nap)
args = ap;
else {
memcpy(copyargs, ap, nap * sizeof(register_t));
error = copyin((void *)frame->tf_usr_sp, copyargs + nap,
(nargs - nap) * sizeof(register_t));
if (error)
goto bad;
args = copyargs;
}
error = 0;
if ((callp->sy_narg & SYF_MPSAFE) == 0)
mtx_lock(&Giant);
locked = 1;
if (error == 0) {
td->td_retval[0] = 0;
td->td_retval[1] = 0;
error = (*callp->sy_call)(td, args);
}
#if 0
printf("code %d error %d\n", code, error);
#endif
switch (error) {
case 0:
frame->tf_r0 = td->td_retval[0];
frame->tf_r1 = td->td_retval[1];
frame->tf_spsr &= ~PSR_C_bit; /* carry bit */
break;
case ERESTART:
/*
* Reconstruct the pc to point at the swi.
*/
frame->tf_pc -= INSN_SIZE;
break;
case EJUSTRETURN:
/* nothing to do */
break;
default:
bad:
frame->tf_r0 = error;
frame->tf_spsr |= PSR_C_bit; /* carry bit */
break;
}
if (locked && (callp->sy_narg & SYF_MPSAFE) == 0)
mtx_unlock(&Giant);
userret(td, frame, td->td_sticks);
mtx_assert(&sched_lock, MA_NOTOWNED);
mtx_assert(&Giant, MA_NOTOWNED);
}
void
swi_handler(trapframe_t *frame)
{
struct thread *td = curthread;
uint32_t insn;
/*
* Enable interrupts if they were enabled before the exception.
* Since all syscalls *should* come from user mode it will always
* be safe to enable them, but check anyway.
* */
if (!(frame->tf_spsr & I32_bit))
enable_interrupts(I32_bit);
/*
* Make sure the program counter is correctly aligned so we
* don't take an alignment fault trying to read the opcode.
*/
if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
trapsignal(td, SIGILL, 0);
userret(td, frame, td->td_sticks);
return;
}
insn = *(u_int32_t *)(frame->tf_pc - INSN_SIZE);
td->td_frame = frame;
syscall(td, frame, insn);
}

131
sys/arm/arm/uio_machdep.c Normal file
View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2004 Alan L. Cox <alc@cs.rice.edu>
* Copyright (c) 1982, 1986, 1991, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/uio.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <machine/vmparam.h>
/*
* Implement uiomove(9) from physical memory using the direct map to
* avoid the creation and destruction of ephemeral mappings.
*/
int
uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
{
struct thread *td = curthread;
struct iovec *iov;
void *cp;
vm_offset_t page_offset;
size_t cnt;
int error = 0;
int save = 0;
KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE,
("uiomove_fromphys: mode"));
KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
("uiomove_fromphys proc"));
if (td != NULL) {
mtx_lock_spin(&sched_lock);
save = td->td_flags & TDF_DEADLKTREAT;
td->td_flags |= TDF_DEADLKTREAT;
mtx_unlock_spin(&sched_lock);
}
while (n > 0 && uio->uio_resid) {
iov = uio->uio_iov;
cnt = iov->iov_len;
if (cnt == 0) {
uio->uio_iov++;
uio->uio_iovcnt--;
continue;
}
if (cnt > n)
cnt = n;
page_offset = offset & PAGE_MASK;
cnt = min(cnt, PAGE_SIZE - page_offset);
cp = (char *)VM_PAGE_TO_PHYS(ma[offset >> PAGE_SHIFT]) +
page_offset;
switch (uio->uio_segflg) {
case UIO_USERSPACE:
if (ticks - PCPU_GET(switchticks) >= hogticks)
uio_yield();
if (uio->uio_rw == UIO_READ)
error = copyout(cp, iov->iov_base, cnt);
else
error = copyin(iov->iov_base, cp, cnt);
if (error)
goto out;
break;
case UIO_SYSSPACE:
if (uio->uio_rw == UIO_READ)
bcopy(cp, iov->iov_base, cnt);
else
bcopy(iov->iov_base, cp, cnt);
break;
case UIO_NOCOPY:
break;
}
iov->iov_base = (char *)iov->iov_base + cnt;
iov->iov_len -= cnt;
uio->uio_resid -= cnt;
uio->uio_offset += cnt;
offset += cnt;
n -= cnt;
}
out:
if (td != NULL && save == 0) {
mtx_lock_spin(&sched_lock);
td->td_flags &= ~TDF_DEADLKTREAT;
mtx_unlock_spin(&sched_lock);
}
return (error);
}

291
sys/arm/arm/undefined.c Normal file
View File

@ -0,0 +1,291 @@
/* $NetBSD: undefined.c,v 1.22 2003/11/29 22:21:29 bjh21 Exp $ */
/*
* Copyright (c) 2001 Ben Harris.
* Copyright (c) 1995 Mark Brinicombe.
* Copyright (c) 1995 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* undefined.c
*
* Fault handler
*
* Created : 06/01/95
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/signal.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/syslog.h>
#include <sys/vmmeter.h>
#include <sys/types.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#ifdef FAST_FPE
#include <sys/acct.h>
#endif
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <machine/asm.h>
#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/undefined.h>
#include <machine/trap.h>
#include <machine/disassem.h>
#ifdef DDB
#include <ddb/db_output.h>
#include <machine/db_machdep.h>
#endif
#ifdef acorn26
#include <machine/machdep.h>
#endif
static int gdb_trapper(u_int, u_int, struct trapframe *, int);
#ifdef FAST_FPE
extern int want_resched;
#endif
LIST_HEAD(, undefined_handler) undefined_handlers[MAX_COPROCS];
void *
install_coproc_handler(int coproc, undef_handler_t handler)
{
struct undefined_handler *uh;
KASSERT(coproc >= 0 && coproc < MAX_COPROCS, ("bad coproc"));
KASSERT(handler != NULL, ("handler is NULL")); /* Used to be legal. */
/* XXX: M_TEMP??? */
MALLOC(uh, struct undefined_handler *, sizeof(*uh), M_TEMP, M_WAITOK);
uh->uh_handler = handler;
install_coproc_handler_static(coproc, uh);
return uh;
}
void
install_coproc_handler_static(int coproc, struct undefined_handler *uh)
{
LIST_INSERT_HEAD(&undefined_handlers[coproc], uh, uh_link);
}
void
remove_coproc_handler(void *cookie)
{
struct undefined_handler *uh = cookie;
LIST_REMOVE(uh, uh_link);
FREE(uh, M_TEMP);
}
static int
gdb_trapper(u_int addr, u_int insn, struct trapframe *frame, int code)
{
struct thread *td;
td = (curthread == NULL) ? &thread0 : curthread;
#if 0
if (insn == GDB_BREAKPOINT || insn == GDB5_BREAKPOINT) {
if (code == FAULT_USER) {
ksiginfo_t ksi;
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGTRAP;
ksi.ksi_code = TRAP_BRKPT;
ksi.ksi_addr = (u_int32_t *)addr;
ksi.ksi_trap = 0;
PROC_LOCK(td->td_proc);
trapsignal(td, &ksi);
PROC_UNLOCK(td->td_proc);
return 0;
}
#ifdef KGDB
return !kgdb_trap(T_BREAKPOINT, frame);
#endif
}
#endif
return 1;
}
static struct undefined_handler gdb_uh;
void
undefined_init()
{
int loop;
/* Not actually necessary -- the initialiser is just NULL */
for (loop = 0; loop < MAX_COPROCS; ++loop)
LIST_INIT(&undefined_handlers[loop]);
/* Install handler for GDB breakpoints */
gdb_uh.uh_handler = gdb_trapper;
install_coproc_handler_static(0, &gdb_uh);
}
void
undefinedinstruction(trapframe_t *frame)
{
struct thread *td;
u_int fault_pc;
int fault_instruction;
int fault_code;
int coprocessor;
struct undefined_handler *uh;
#ifdef VERBOSE_ARM32
int s;
#endif
/* Enable interrupts if they were enabled before the exception. */
if (!(frame->tf_spsr & I32_bit))
enable_interrupts(I32_bit);
frame->tf_pc -= INSN_SIZE;
fault_pc = frame->tf_pc;
/*
* Get the current thread/proc structure or thread0/proc0 if there is
* none.
*/
td = curthread == NULL ? &thread0 : curthread;
/*
* Make sure the program counter is correctly aligned so we
* don't take an alignment fault trying to read the opcode.
*/
if (__predict_false((fault_pc & 3) != 0)) {
trapsignal(td, SIGILL, 0);
userret(td, frame, 0);
return;
}
/*
* Should use fuword() here .. but in the interests of squeezing every
* bit of speed we will just use ReadWord(). We know the instruction
* can be read as was just executed so this will never fail unless the
* kernel is screwed up in which case it does not really matter does
* it ?
*/
fault_instruction = *(u_int32_t *)fault_pc;
/* Update vmmeter statistics */
#if 0
uvmexp.traps++;
#endif
/* Check for coprocessor instruction */
/*
* According to the datasheets you only need to look at bit 27 of the
* instruction to tell the difference between and undefined
* instruction and a coprocessor instruction following an undefined
* instruction trap.
*/
if ((fault_instruction & (1 << 27)) != 0)
coprocessor = (fault_instruction >> 8) & 0x0f;
else
coprocessor = 0;
if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE) {
/*
* Modify the fault_code to reflect the USR/SVC state at
* time of fault.
*/
fault_code = FAULT_USER;
td->td_frame = frame;
} else
fault_code = 0;
/* OK this is were we do something about the instruction. */
LIST_FOREACH(uh, &undefined_handlers[coprocessor], uh_link)
if (uh->uh_handler(fault_pc, fault_instruction, frame,
fault_code) == 0)
break;
if (uh == NULL) {
/* Fault has not been handled */
trapsignal(td, SIGILL, 0);
}
if ((fault_code & FAULT_USER) == 0)
return;
#ifdef FAST_FPE
/* Optimised exit code */
{
/*
* Check for reschedule request, at the moment there is only
* 1 ast so this code should always be run
*/
if (want_resched) {
/*
* We are being preempted.
*/
preempt(0);
}
/* Invoke MI userret code */
mi_userret(td);
#if 0
l->l_priority = l->l_usrpri;
curcpu()->ci_schedstate.spc_curpriority = l->l_priority;
#endif
}
#else
userret(td, frame, 0);
#endif
}

104
sys/arm/arm/vectors.S Normal file
View File

@ -0,0 +1,104 @@
/* $NetBSD: vectors.S,v 1.4 2002/08/17 16:36:32 thorpej Exp $ */
/*
* Copyright (C) 1994-1997 Mark Brinicombe
* Copyright (C) 1994 Brini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of Brini may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* These are the exception vectors copied down to page 0.
*
* Note that FIQs are special; rather than using a level of
* indirection, we actually copy the FIQ code down into the
* vector page.
*/
.text
.align 0
.global _C_LABEL(page0), _C_LABEL(page0_data), _C_LABEL(page0_end)
.global _C_LABEL(fiqvector)
_C_LABEL(page0):
ldr pc, .Lreset_target
ldr pc, .Lundefined_target
ldr pc, .Lswi_target
ldr pc, .Lprefetch_abort_target
ldr pc, .Ldata_abort_target
ldr pc, .Laddress_exception_target
ldr pc, .Lirq_target
#ifdef __ARM_FIQ_INDIRECT
ldr pc, .Lfiq_target
#else
.Lfiqvector:
.set _C_LABEL(fiqvector), . - _C_LABEL(page0)
subs pc, lr, #4
.org .Lfiqvector + 0x100
#endif
_C_LABEL(page0_data):
.Lreset_target:
.word reset_entry
.Lundefined_target:
.word undefined_entry
.Lswi_target:
.word swi_entry
.Lprefetch_abort_target:
.word prefetch_abort_entry
.Ldata_abort_target:
.word data_abort_entry
.Laddress_exception_target:
.word address_exception_entry
.Lirq_target:
.word irq_entry
#ifdef __ARM_FIQ_INDIRECT
.Lfiq_target:
.word _C_LABEL(fiqvector)
#else
.word 0 /* pad it out */
#endif
_C_LABEL(page0_end):
#ifdef __ARM_FIQ_INDIRECT
.data
.align 0
_C_LABEL(fiqvector):
subs pc, lr, #4
.org _C_LABEL(fiqvector) + 0x100
#endif

348
sys/arm/arm/vm_machdep.c Normal file
View File

@ -0,0 +1,348 @@
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
* Copyright (c) 1989, 1990 William Jolitz
* Copyright (c) 1994 John Dyson
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
* Science Department, and William Jolitz.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
*//*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
* Copyright (c) 1989, 1990 William Jolitz
* Copyright (c) 1994 John Dyson
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
* Science Department, and William Jolitz.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/proc.h>
#include <sys/socketvar.h>
#include <sys/sf_buf.h>
#include <sys/user.h>
#include <machine/cpu.h>
#include <machine/pcb.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <vm/vm_param.h>
static void sf_buf_init(void *arg);
SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL)
LIST_HEAD(sf_head, sf_buf);
/*
* A hash table of active sendfile(2) buffers
*/
static struct sf_head *sf_buf_active;
static u_long sf_buf_hashmask;
#define SF_BUF_HASH(m) (((m) - vm_page_array) & sf_buf_hashmask)
static TAILQ_HEAD(, sf_buf) sf_buf_freelist;
static u_int sf_buf_alloc_want;
/*
* A lock used to synchronize access to the hash table and free list
*/
static struct mtx sf_buf_lock;
/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the pcb, set up the stack so that the child
* ready to run and return to user mode.
*/
void
cpu_fork(register struct thread *td1, register struct proc *p2,
struct thread *td2, int flags)
{
struct pcb *pcb1, *pcb2;
struct trapframe *tf;
struct switchframe *sf;
struct mdproc *mdp2;
pcb1 = td1->td_pcb;
pcb2 = (struct pcb *)(td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1;
td2->td_pcb = pcb2;
bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
mdp2 = &p2->p_md;
bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
pcb2->un_32.pcb32_und_sp = (u_int)td2->td_kstack + USPACE_UNDEF_STACK_TOP;
pcb2->un_32.pcb32_sp = (u_int)td2->td_kstack +
USPACE_SVC_STACK_TOP;
pmap_activate(td2);
td2->td_frame = tf =
(struct trapframe *)pcb2->un_32.pcb32_sp - 1;
*tf = *td1->td_frame;
sf = (struct switchframe *)tf - 1;
sf->sf_r4 = (u_int)fork_return;
sf->sf_r5 = (u_int)td2;
sf->sf_pc = (u_int)fork_trampoline;
tf->tf_spsr &= ~PSR_C_bit;
tf->tf_r0 = 0;
pcb2->un_32.pcb32_sp = (u_int)sf;
}
void
cpu_thread_swapin(struct thread *td)
{
}
void
cpu_thread_swapout(struct thread *td)
{
}
/*
* Detatch mapped page and release resources back to the system.
*/
void
sf_buf_free(struct sf_buf *sf)
{
mtx_lock(&sf_buf_lock);
sf->ref_count--;
if (sf->ref_count == 0) {
TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry);
nsfbufsused--;
if (sf_buf_alloc_want > 0)
wakeup_one(&sf_buf_freelist);
}
mtx_unlock(&sf_buf_lock);
}
/*
* * Allocate a pool of sf_bufs (sendfile(2) or "super-fast" if you prefer. :-))
* */
static void
sf_buf_init(void *arg)
{
struct sf_buf *sf_bufs;
vm_offset_t sf_base;
int i;
sf_buf_active = hashinit(nsfbufs, M_TEMP, &sf_buf_hashmask);
TAILQ_INIT(&sf_buf_freelist);
sf_base = kmem_alloc_nofault(kernel_map, nsfbufs * PAGE_SIZE);
sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP,
M_NOWAIT | M_ZERO);
for (i = 0; i < nsfbufs; i++) {
sf_bufs[i].kva = sf_base + i * PAGE_SIZE;
TAILQ_INSERT_TAIL(&sf_buf_freelist, &sf_bufs[i], free_entry);
}
sf_buf_alloc_want = 0;
mtx_init(&sf_buf_lock, "sf_buf", NULL, MTX_DEF);
}
/*
* Get an sf_buf from the freelist. Will block if none are available.
*/
struct sf_buf *
sf_buf_alloc(struct vm_page *m, int pri)
{
struct sf_head *hash_list;
struct sf_buf *sf;
int error;
hash_list = &sf_buf_active[SF_BUF_HASH(m)];
mtx_lock(&sf_buf_lock);
LIST_FOREACH(sf, hash_list, list_entry) {
if (sf->m == m) {
sf->ref_count++;
if (sf->ref_count == 1) {
TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
nsfbufsused++;
nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
}
goto done;
}
}
while ((sf = TAILQ_FIRST(&sf_buf_freelist)) == NULL) {
sf_buf_alloc_want++;
mbstat.sf_allocwait++;
error = msleep(&sf_buf_freelist, &sf_buf_lock, PVM | pri,
"sfbufa", 0);
sf_buf_alloc_want--;
/*
* If we got a signal, don't risk going back to sleep.
*/
if (error)
goto done;
}
TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
if (sf->m != NULL)
LIST_REMOVE(sf, list_entry);
LIST_INSERT_HEAD(hash_list, sf, list_entry);
sf->ref_count = 1;
sf->m = m;
nsfbufsused++;
nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
pmap_qenter(sf->kva, &sf->m, 1);
done:
mtx_unlock(&sf_buf_lock);
return (sf);
}
/*
* Initialize machine state (pcb and trap frame) for a new thread about to
* upcall. Put enough state in the new thread's PCB to get it to go back
* userret(), where we can intercept it again to set the return (upcall)
* Address and stack, along with those from upcals that are from other sources
* such as those generated in thread_userret() itself.
*/
void
cpu_set_upcall(struct thread *td, struct thread *td0)
{
panic("set upcall\n");
}
/*
* Set that machine state for performing an upcall that has to
* be done in thread_userret() so that those upcalls generated
* in thread_userret() itself can be done as well.
*/
void
cpu_set_upcall_kse(struct thread *td, struct kse_upcall *ku)
{
panic("setupcallkse\n");
}
void
cpu_thread_exit(struct thread *td)
{
}
void
cpu_thread_setup(struct thread *td)
{
td->td_pcb = (struct pcb *)(td->td_kstack + KSTACK_PAGES *
PAGE_SIZE) - 1;
td->td_frame = (struct trapframe *)
((u_int)td->td_kstack + USPACE_SVC_STACK_TOP) - 1;
}
void
cpu_thread_clean(struct thread *td)
{
}
/*
* Intercept the return address from a freshly forked process that has NOT
* been scheduled yet.
*
* This is needed to make kernel threads stay in kernel mode.
*/
void
cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg)
{
struct switchframe *sf;
struct trapframe *tf;
tf = td->td_frame;
sf = (struct switchframe *)tf - 1;
sf->sf_r4 = (u_int)func;
sf->sf_r5 = (u_int)arg;
td->td_pcb->un_32.pcb32_sp = (u_int)sf;
}
/*
* Software interrupt handler for queued VM system processing.
*/
void
swi_vm(void *dummy)
{
}
void
cpu_exit(struct thread *td)
{
}
void
cpu_sched_exit(td)
register struct thread *td;
{
}

83
sys/arm/conf/SIMICS Normal file
View File

@ -0,0 +1,83 @@
# GENERIC -- Generic kernel configuration file for FreeBSD/i386
#
# For more information on this file, please read the handbook section on
# Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
# The handbook is also available locally in /usr/share/doc/handbook
# if you've installed the doc distribution, otherwise always see the
# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
# latest information.
#
# An exhaustive list of options and more detailed explanations of the
# device lines is also present in the ../../conf/NOTES and NOTES files.
# If you are in doubt as to the purpose or necessity of a line, check first
# in NOTES.
#
# $FreeBSD$
machine arm
ident SIMICS
options KERNPHYSADDR=0xc0000000
include "../sa11x0/std.sa11x0"
#To statically compile in device wiring instead of /boot/device.hints
#hints "GENERIC.hints" #Default places to look for devices.
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
makeoptions CONF_CFLAGS=-mcpu=strongarm
options DDB
options SCHED_4BSD #4BSD scheduler
options INET #InterNETworking
options INET6 #IPv6 communications protocols
options FFS #Berkeley Fast Filesystem
options SOFTUPDATES #Enable FFS soft updates support
options UFS_ACL #Support for access control lists
options UFS_DIRHASH #Improve performance on big directories
options MD_ROOT #MD is a potential root device
options ROOTDEVNAME=\"ufs:md0\"
options NFSCLIENT #Network Filesystem Client
options NFSSERVER #Network Filesystem Server
options NFS_ROOT #NFS usable as /, requires NFSCLIENT
#options MSDOSFS #MSDOS Filesystem
options CD9660 #ISO 9660 Filesystem
#options PROCFS #Process filesystem (requires PSEUDOFS)
options PSEUDOFS #Pseudo-filesystem framework
options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=15000 #Delay (in ms) before probing SCSI
#options KTRACE #ktrace(1) support
options SYSVSHM #SYSV-style shared memory
options SYSVMSG #SYSV-style message queues
options SYSVSEM #SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
device genclock
device loop
device ether
device saip
device assabet
device nexus
#device saarm
device rl
device uart
#options AHC_REG_PRETTY_PRINT # Print register bitfields in debug
# output. Adds ~128k to driver.
#options AHD_REG_PRETTY_PRINT # Print register bitfields in debug
# output. Adds ~215k to driver.
# Debugging for use in -current
options DDB #Enable the kernel debugger
#options INVARIANTS #Enable calls of extra sanity checking
#options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS
#options WITNESS #Enable checks to detect deadlocks and cycles
#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed
# To make an SMP kernel, the next two are needed
#options SMP # Symmetric MultiProcessor Kernel
#options APIC_IO # Symmetric (APIC) I/O
device md
# Floppy drives

220
sys/arm/include/_inttypes.h Normal file
View File

@ -0,0 +1,220 @@
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Klaus Klein.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* From: $NetBSD: int_fmtio.h,v 1.2 2001/04/26 16:25:21 kleink Exp $
* $FreeBSD$
*/
#ifndef _MACHINE_INTTYPES_H_
#define _MACHINE_INTTYPES_H_
/*
* Macros for format specifiers.
*/
/* fprintf(3) macros for signed integers. */
#define PRId8 "d" /* int8_t */
#define PRId16 "d" /* int16_t */
#define PRId32 "d" /* int32_t */
#define PRId64 "lld" /* int64_t */
#define PRIdLEAST8 "d" /* int_least8_t */
#define PRIdLEAST16 "d" /* int_least16_t */
#define PRIdLEAST32 "d" /* int_least32_t */
#define PRIdLEAST64 "lld" /* int_least64_t */
#define PRIdFAST8 "d" /* int_fast8_t */
#define PRIdFAST16 "d" /* int_fast16_t */
#define PRIdFAST32 "d" /* int_fast32_t */
#define PRIdFAST64 "lld" /* int_fast64_t */
#define PRIdMAX "jd" /* intmax_t */
#define PRIdPTR "d" /* intptr_t */
#define PRIi8 "i" /* int8_t */
#define PRIi16 "i" /* int16_t */
#define PRIi32 "i" /* int32_t */
#define PRIi64 "lli" /* int64_t */
#define PRIiLEAST8 "i" /* int_least8_t */
#define PRIiLEAST16 "i" /* int_least16_t */
#define PRIiLEAST32 "i" /* int_least32_t */
#define PRIiLEAST64 "lli" /* int_least64_t */
#define PRIiFAST8 "i" /* int_fast8_t */
#define PRIiFAST16 "i" /* int_fast16_t */
#define PRIiFAST32 "i" /* int_fast32_t */
#define PRIiFAST64 "lli" /* int_fast64_t */
#define PRIiMAX "ji" /* intmax_t */
#define PRIiPTR "i" /* intptr_t */
/* fprintf(3) macros for unsigned integers. */
#define PRIo8 "o" /* uint8_t */
#define PRIo16 "o" /* uint16_t */
#define PRIo32 "o" /* uint32_t */
#define PRIo64 "llo" /* uint64_t */
#define PRIoLEAST8 "o" /* uint_least8_t */
#define PRIoLEAST16 "o" /* uint_least16_t */
#define PRIoLEAST32 "o" /* uint_least32_t */
#define PRIoLEAST64 "llo" /* uint_least64_t */
#define PRIoFAST8 "o" /* uint_fast8_t */
#define PRIoFAST16 "o" /* uint_fast16_t */
#define PRIoFAST32 "o" /* uint_fast32_t */
#define PRIoFAST64 "llo" /* uint_fast64_t */
#define PRIoMAX "jo" /* uintmax_t */
#define PRIoPTR "o" /* uintptr_t */
#define PRIu8 "u" /* uint8_t */
#define PRIu16 "u" /* uint16_t */
#define PRIu32 "u" /* uint32_t */
#define PRIu64 "llu" /* uint64_t */
#define PRIuLEAST8 "u" /* uint_least8_t */
#define PRIuLEAST16 "u" /* uint_least16_t */
#define PRIuLEAST32 "u" /* uint_least32_t */
#define PRIuLEAST64 "llu" /* uint_least64_t */
#define PRIuFAST8 "u" /* uint_fast8_t */
#define PRIuFAST16 "u" /* uint_fast16_t */
#define PRIuFAST32 "u" /* uint_fast32_t */
#define PRIuFAST64 "llu" /* uint_fast64_t */
#define PRIuMAX "ju" /* uintmax_t */
#define PRIuPTR "u" /* uintptr_t */
#define PRIx8 "x" /* uint8_t */
#define PRIx16 "x" /* uint16_t */
#define PRIx32 "x" /* uint32_t */
#define PRIx64 "llx" /* uint64_t */
#define PRIxLEAST8 "x" /* uint_least8_t */
#define PRIxLEAST16 "x" /* uint_least16_t */
#define PRIxLEAST32 "x" /* uint_least32_t */
#define PRIxLEAST64 "llx" /* uint_least64_t */
#define PRIxFAST8 "x" /* uint_fast8_t */
#define PRIxFAST16 "x" /* uint_fast16_t */
#define PRIxFAST32 "x" /* uint_fast32_t */
#define PRIxFAST64 "llx" /* uint_fast64_t */
#define PRIxMAX "jx" /* uintmax_t */
#define PRIxPTR "x" /* uintptr_t */
#define PRIX8 "X" /* uint8_t */
#define PRIX16 "X" /* uint16_t */
#define PRIX32 "X" /* uint32_t */
#define PRIX64 "llX" /* uint64_t */
#define PRIXLEAST8 "X" /* uint_least8_t */
#define PRIXLEAST16 "X" /* uint_least16_t */
#define PRIXLEAST32 "X" /* uint_least32_t */
#define PRIXLEAST64 "llX" /* uint_least64_t */
#define PRIXFAST8 "X" /* uint_fast8_t */
#define PRIXFAST16 "X" /* uint_fast16_t */
#define PRIXFAST32 "X" /* uint_fast32_t */
#define PRIXFAST64 "llX" /* uint_fast64_t */
#define PRIXMAX "jX" /* uintmax_t */
#define PRIXPTR "X" /* uintptr_t */
/* fscanf(3) macros for signed integers. */
#define SCNd8 "hhd" /* int8_t */
#define SCNd16 "hd" /* int16_t */
#define SCNd32 "d" /* int32_t */
#define SCNd64 "lld" /* int64_t */
#define SCNdLEAST8 "hhd" /* int_least8_t */
#define SCNdLEAST16 "hd" /* int_least16_t */
#define SCNdLEAST32 "d" /* int_least32_t */
#define SCNdLEAST64 "lld" /* int_least64_t */
#define SCNdFAST8 "d" /* int_fast8_t */
#define SCNdFAST16 "d" /* int_fast16_t */
#define SCNdFAST32 "d" /* int_fast32_t */
#define SCNdFAST64 "lld" /* int_fast64_t */
#define SCNdMAX "jd" /* intmax_t */
#define SCNdPTR "d" /* intptr_t */
#define SCNi8 "hhi" /* int8_t */
#define SCNi16 "hi" /* int16_t */
#define SCNi32 "i" /* int32_t */
#define SCNi64 "lli" /* int64_t */
#define SCNiLEAST8 "hhi" /* int_least8_t */
#define SCNiLEAST16 "hi" /* int_least16_t */
#define SCNiLEAST32 "i" /* int_least32_t */
#define SCNiLEAST64 "lli" /* int_least64_t */
#define SCNiFAST8 "i" /* int_fast8_t */
#define SCNiFAST16 "i" /* int_fast16_t */
#define SCNiFAST32 "i" /* int_fast32_t */
#define SCNiFAST64 "lli" /* int_fast64_t */
#define SCNiMAX "ji" /* intmax_t */
#define SCNiPTR "i" /* intptr_t */
/* fscanf(3) macros for unsigned integers. */
#define SCNo8 "hho" /* uint8_t */
#define SCNo16 "ho" /* uint16_t */
#define SCNo32 "o" /* uint32_t */
#define SCNo64 "llo" /* uint64_t */
#define SCNoLEAST8 "hho" /* uint_least8_t */
#define SCNoLEAST16 "ho" /* uint_least16_t */
#define SCNoLEAST32 "o" /* uint_least32_t */
#define SCNoLEAST64 "llo" /* uint_least64_t */
#define SCNoFAST8 "o" /* uint_fast8_t */
#define SCNoFAST16 "o" /* uint_fast16_t */
#define SCNoFAST32 "o" /* uint_fast32_t */
#define SCNoFAST64 "llo" /* uint_fast64_t */
#define SCNoMAX "jo" /* uintmax_t */
#define SCNoPTR "o" /* uintptr_t */
#define SCNu8 "hhu" /* uint8_t */
#define SCNu16 "hu" /* uint16_t */
#define SCNu32 "u" /* uint32_t */
#define SCNu64 "llu" /* uint64_t */
#define SCNuLEAST8 "hhu" /* uint_least8_t */
#define SCNuLEAST16 "hu" /* uint_least16_t */
#define SCNuLEAST32 "u" /* uint_least32_t */
#define SCNuLEAST64 "llu" /* uint_least64_t */
#define SCNuFAST8 "u" /* uint_fast8_t */
#define SCNuFAST16 "u" /* uint_fast16_t */
#define SCNuFAST32 "u" /* uint_fast32_t */
#define SCNuFAST64 "llu" /* uint_fast64_t */
#define SCNuMAX "ju" /* uintmax_t */
#define SCNuPTR "u" /* uintptr_t */
#define SCNx8 "hhx" /* uint8_t */
#define SCNx16 "hx" /* uint16_t */
#define SCNx32 "x" /* uint32_t */
#define SCNx64 "llx" /* uint64_t */
#define SCNxLEAST8 "hhx" /* uint_least8_t */
#define SCNxLEAST16 "hx" /* uint_least16_t */
#define SCNxLEAST32 "x" /* uint_least32_t */
#define SCNxLEAST64 "llx" /* uint_least64_t */
#define SCNxFAST8 "x" /* uint_fast8_t */
#define SCNxFAST16 "x" /* uint_fast16_t */
#define SCNxFAST32 "x" /* uint_fast32_t */
#define SCNxFAST64 "llx" /* uint_fast64_t */
#define SCNxMAX "jx" /* uintmax_t */
#define SCNxPTR "x" /* uintptr_t */
#endif /* !_MACHINE_INTTYPES_H_ */

299
sys/arm/include/armreg.h Normal file
View File

@ -0,0 +1,299 @@
/* $NetBSD: armreg.h,v 1.28 2003/10/31 16:30:15 scw Exp $ */
/*
* Copyright (c) 1998, 2001 Ben Harris
* Copyright (c) 1994-1996 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef MACHINE_ARMREG_H
#define MACHINE_ARMREG_H
#define INSN_SIZE 4
#define INSN_COND_MASK 0xf0000000 /* Condition mask */
#define PSR_MODE 0x0000001f /* mode mask */
#define PSR_USR26_MODE 0x00000000
#define PSR_FIQ26_MODE 0x00000001
#define PSR_IRQ26_MODE 0x00000002
#define PSR_SVC26_MODE 0x00000003
#define PSR_USR32_MODE 0x00000010
#define PSR_FIQ32_MODE 0x00000011
#define PSR_IRQ32_MODE 0x00000012
#define PSR_SVC32_MODE 0x00000013
#define PSR_ABT32_MODE 0x00000017
#define PSR_UND32_MODE 0x0000001b
#define PSR_SYS32_MODE 0x0000001f
#define PSR_32_MODE 0x00000010
#define PSR_FLAGS 0xf0000000 /* flags */
#define PSR_C_bit (1 << 29) /* carry */
/* The high-order byte is always the implementor */
#define CPU_ID_IMPLEMENTOR_MASK 0xff000000
#define CPU_ID_ARM_LTD 0x41000000 /* 'A' */
#define CPU_ID_DEC 0x44000000 /* 'D' */
#define CPU_ID_INTEL 0x69000000 /* 'i' */
#define CPU_ID_TI 0x54000000 /* 'T' */
/* How to decide what format the CPUID is in. */
#define CPU_ID_ISOLD(x) (((x) & 0x0000f000) == 0x00000000)
#define CPU_ID_IS7(x) (((x) & 0x0000f000) == 0x00007000)
#define CPU_ID_ISNEW(x) (!CPU_ID_ISOLD(x) && !CPU_ID_IS7(x))
/* On ARM3 and ARM6, this byte holds the foundry ID. */
#define CPU_ID_FOUNDRY_MASK 0x00ff0000
#define CPU_ID_FOUNDRY_VLSI 0x00560000
/* On ARM7 it holds the architecture and variant (sub-model) */
#define CPU_ID_7ARCH_MASK 0x00800000
#define CPU_ID_7ARCH_V3 0x00000000
#define CPU_ID_7ARCH_V4T 0x00800000
#define CPU_ID_7VARIANT_MASK 0x007f0000
/* On more recent ARMs, it does the same, but in a different format */
#define CPU_ID_ARCH_MASK 0x000f0000
#define CPU_ID_ARCH_V3 0x00000000
#define CPU_ID_ARCH_V4 0x00010000
#define CPU_ID_ARCH_V4T 0x00020000
#define CPU_ID_ARCH_V5 0x00030000
#define CPU_ID_ARCH_V5T 0x00040000
#define CPU_ID_ARCH_V5TE 0x00050000
#define CPU_ID_VARIANT_MASK 0x00f00000
/* Next three nybbles are part number */
#define CPU_ID_PARTNO_MASK 0x0000fff0
/* Intel XScale has sub fields in part number */
#define CPU_ID_XSCALE_COREGEN_MASK 0x0000e000 /* core generation */
#define CPU_ID_XSCALE_COREREV_MASK 0x00001c00 /* core revision */
#define CPU_ID_XSCALE_PRODUCT_MASK 0x000003f0 /* product number */
/* And finally, the revision number. */
#define CPU_ID_REVISION_MASK 0x0000000f
/* Individual CPUs are probably best IDed by everything but the revision. */
#define CPU_ID_CPU_MASK 0xfffffff0
/* Fake CPU IDs for ARMs without CP15 */
#define CPU_ID_ARM2 0x41560200
#define CPU_ID_ARM250 0x41560250
/* Pre-ARM7 CPUs -- [15:12] == 0 */
#define CPU_ID_ARM3 0x41560300
#define CPU_ID_ARM600 0x41560600
#define CPU_ID_ARM610 0x41560610
#define CPU_ID_ARM620 0x41560620
/* ARM7 CPUs -- [15:12] == 7 */
#define CPU_ID_ARM700 0x41007000 /* XXX This is a guess. */
#define CPU_ID_ARM710 0x41007100
#define CPU_ID_ARM7500 0x41027100 /* XXX This is a guess. */
#define CPU_ID_ARM710A 0x41047100 /* inc ARM7100 */
#define CPU_ID_ARM7500FE 0x41077100
#define CPU_ID_ARM710T 0x41807100
#define CPU_ID_ARM720T 0x41807200
#define CPU_ID_ARM740T8K 0x41807400 /* XXX no MMU, 8KB cache */
#define CPU_ID_ARM740T4K 0x41817400 /* XXX no MMU, 4KB cache */
/* Post-ARM7 CPUs */
#define CPU_ID_ARM810 0x41018100
#define CPU_ID_ARM920T 0x41129200
#define CPU_ID_ARM922T 0x41029220
#define CPU_ID_ARM940T 0x41029400 /* XXX no MMU */
#define CPU_ID_ARM946ES 0x41049460 /* XXX no MMU */
#define CPU_ID_ARM966ES 0x41049660 /* XXX no MMU */
#define CPU_ID_ARM966ESR1 0x41059660 /* XXX no MMU */
#define CPU_ID_ARM1020E 0x4115a200 /* (AKA arm10 rev 1) */
#define CPU_ID_ARM1022ES 0x4105a220
#define CPU_ID_SA110 0x4401a100
#define CPU_ID_SA1100 0x4401a110
#define CPU_ID_TI925T 0x54029250
#define CPU_ID_SA1110 0x6901b110
#define CPU_ID_IXP1200 0x6901c120
#define CPU_ID_80200 0x69052000
#define CPU_ID_PXA250 0x69052100 /* sans core revision */
#define CPU_ID_PXA210 0x69052120
#define CPU_ID_PXA250A 0x69052100 /* 1st version Core */
#define CPU_ID_PXA210A 0x69052120 /* 1st version Core */
#define CPU_ID_PXA250B 0x69052900 /* 3rd version Core */
#define CPU_ID_PXA210B 0x69052920 /* 3rd version Core */
#define CPU_ID_PXA250C 0x69052d00 /* 4th version Core */
#define CPU_ID_PXA210C 0x69052d20 /* 4th version Core */
#define CPU_ID_80321_400 0x69052420
#define CPU_ID_80321_600 0x69052430
#define CPU_ID_80321_400_B0 0x69052c20
#define CPU_ID_80321_600_B0 0x69052c30
#define CPU_ID_IXP425_533 0x690541c0
#define CPU_ID_IXP425_400 0x690541d0
#define CPU_ID_IXP425_266 0x690541f0
/* ARM3-specific coprocessor 15 registers */
#define ARM3_CP15_FLUSH 1
#define ARM3_CP15_CONTROL 2
#define ARM3_CP15_CACHEABLE 3
#define ARM3_CP15_UPDATEABLE 4
#define ARM3_CP15_DISRUPTIVE 5
/* ARM3 Control register bits */
#define ARM3_CTL_CACHE_ON 0x00000001
#define ARM3_CTL_SHARED 0x00000002
#define ARM3_CTL_MONITOR 0x00000004
/*
* Post-ARM3 CP15 registers:
*
* 1 Control register
*
* 2 Translation Table Base
*
* 3 Domain Access Control
*
* 4 Reserved
*
* 5 Fault Status
*
* 6 Fault Address
*
* 7 Cache/write-buffer Control
*
* 8 TLB Control
*
* 9 Cache Lockdown
*
* 10 TLB Lockdown
*
* 11 Reserved
*
* 12 Reserved
*
* 13 Process ID (for FCSE)
*
* 14 Reserved
*
* 15 Implementation Dependent
*/
/* Some of the definitions below need cleaning up for V3/V4 architectures */
/* CPU control register (CP15 register 1) */
#define CPU_CONTROL_MMU_ENABLE 0x00000001 /* M: MMU/Protection unit enable */
#define CPU_CONTROL_AFLT_ENABLE 0x00000002 /* A: Alignment fault enable */
#define CPU_CONTROL_DC_ENABLE 0x00000004 /* C: IDC/DC enable */
#define CPU_CONTROL_WBUF_ENABLE 0x00000008 /* W: Write buffer enable */
#define CPU_CONTROL_32BP_ENABLE 0x00000010 /* P: 32-bit exception handlers */
#define CPU_CONTROL_32BD_ENABLE 0x00000020 /* D: 32-bit addressing */
#define CPU_CONTROL_LABT_ENABLE 0x00000040 /* L: Late abort enable */
#define CPU_CONTROL_BEND_ENABLE 0x00000080 /* B: Big-endian mode */
#define CPU_CONTROL_SYST_ENABLE 0x00000100 /* S: System protection bit */
#define CPU_CONTROL_ROM_ENABLE 0x00000200 /* R: ROM protection bit */
#define CPU_CONTROL_CPCLK 0x00000400 /* F: Implementation defined */
#define CPU_CONTROL_BPRD_ENABLE 0x00000800 /* Z: Branch prediction enable */
#define CPU_CONTROL_IC_ENABLE 0x00001000 /* I: IC enable */
#define CPU_CONTROL_VECRELOC 0x00002000 /* V: Vector relocation */
#define CPU_CONTROL_ROUNDROBIN 0x00004000 /* RR: Predictable replacement */
#define CPU_CONTROL_V4COMPAT 0x00008000 /* L4: ARMv4 compat LDR R15 etc */
#define CPU_CONTROL_IDC_ENABLE CPU_CONTROL_DC_ENABLE
/* XScale Auxillary Control Register (CP15 register 1, opcode2 1) */
#define XSCALE_AUXCTL_K 0x00000001 /* dis. write buffer coalescing */
#define XSCALE_AUXCTL_P 0x00000002 /* ECC protect page table access */
#define XSCALE_AUXCTL_MD_WB_RA 0x00000000 /* mini-D$ wb, read-allocate */
#define XSCALE_AUXCTL_MD_WB_RWA 0x00000010 /* mini-D$ wb, read/write-allocate */
#define XSCALE_AUXCTL_MD_WT 0x00000020 /* mini-D$ wt, read-allocate */
#define XSCALE_AUXCTL_MD_MASK 0x00000030
/* Cache type register definitions */
#define CPU_CT_ISIZE(x) ((x) & 0xfff) /* I$ info */
#define CPU_CT_DSIZE(x) (((x) >> 12) & 0xfff) /* D$ info */
#define CPU_CT_S (1U << 24) /* split cache */
#define CPU_CT_CTYPE(x) (((x) >> 25) & 0xf) /* cache type */
#define CPU_CT_CTYPE_WT 0 /* write-through */
#define CPU_CT_CTYPE_WB1 1 /* write-back, clean w/ read */
#define CPU_CT_CTYPE_WB2 2 /* w/b, clean w/ cp15,7 */
#define CPU_CT_CTYPE_WB6 6 /* w/b, cp15,7, lockdown fmt A */
#define CPU_CT_CTYPE_WB7 7 /* w/b, cp15,7, lockdown fmt B */
#define CPU_CT_xSIZE_LEN(x) ((x) & 0x3) /* line size */
#define CPU_CT_xSIZE_M (1U << 2) /* multiplier */
#define CPU_CT_xSIZE_ASSOC(x) (((x) >> 3) & 0x7) /* associativity */
#define CPU_CT_xSIZE_SIZE(x) (((x) >> 6) & 0x7) /* size */
/* Fault status register definitions */
#define FAULT_TYPE_MASK 0x0f
#define FAULT_USER 0x10
#define FAULT_WRTBUF_0 0x00 /* Vector Exception */
#define FAULT_WRTBUF_1 0x02 /* Terminal Exception */
#define FAULT_BUSERR_0 0x04 /* External Abort on Linefetch -- Section */
#define FAULT_BUSERR_1 0x06 /* External Abort on Linefetch -- Page */
#define FAULT_BUSERR_2 0x08 /* External Abort on Non-linefetch -- Section */
#define FAULT_BUSERR_3 0x0a /* External Abort on Non-linefetch -- Page */
#define FAULT_BUSTRNL1 0x0c /* External abort on Translation -- Level 1 */
#define FAULT_BUSTRNL2 0x0e /* External abort on Translation -- Level 2 */
#define FAULT_ALIGN_0 0x01 /* Alignment */
#define FAULT_ALIGN_1 0x03 /* Alignment */
#define FAULT_TRANS_S 0x05 /* Translation -- Section */
#define FAULT_TRANS_P 0x07 /* Translation -- Page */
#define FAULT_DOMAIN_S 0x09 /* Domain -- Section */
#define FAULT_DOMAIN_P 0x0b /* Domain -- Page */
#define FAULT_PERM_S 0x0d /* Permission -- Section */
#define FAULT_PERM_P 0x0f /* Permission -- Page */
#define FAULT_IMPRECISE 0x400 /* Imprecise exception (XSCALE) */
/*
* Address of the vector page, low and high versions.
*/
#define ARM_VECTORS_LOW 0x00000000U
#define ARM_VECTORS_HIGH 0xffff0000U
/*
* ARM Instructions
*
* 3 3 2 2 2
* 1 0 9 8 7 0
* +-------+-------------------------------------------------------+
* | cond | instruction dependant |
* |c c c c| |
* +-------+-------------------------------------------------------+
*/
#define INSN_SIZE 4 /* Always 4 bytes */
#define INSN_COND_MASK 0xf0000000 /* Condition mask */
#define INSN_COND_AL 0xe0000000 /* Always condition */
#endif /* !MACHINE_ARMREG_H */

147
sys/arm/include/asm.h Normal file
View File

@ -0,0 +1,147 @@
/* $NetBSD: asm.h,v 1.5 2003/08/07 16:26:53 agc Exp $ */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)asm.h 5.5 (Berkeley) 5/7/91
*
* $FreeBSD$
*/
#ifndef _MACHINE_ASM_H_
#define _MACHINE_ASM_H_
#include <sys/cdefs.h>
#ifdef __ELF__
# define _C_LABEL(x) x
#else
# ifdef __STDC__
# define _C_LABEL(x) _ ## x
# else
# define _C_LABEL(x) _/**/x
# endif
#endif
#define _ASM_LABEL(x) x
#ifndef _JB_MAGIC__SETJMP
#define _JB_MAGIC__SETJMP 0x4278f500
#define _JB_MAGIC_SETJMP 0x4278f501
#endif
#if 0
#ifdef __STDC__
# define __CONCAT(x,y) x ## y
# define __STRING(x) #x
#else
# define __CONCAT(x,y) x/**/y
# define __STRING(x) "x"
#endif
#endif
#define I32_bit (1 << 7) /* IRQ disable */
#define F32_bit (1 << 6) /* FIQ disable */
#define CPU_CONTROL_32BP_ENABLE 0x00000010 /* P: 32-bit exception handlers */
#define CPU_CONTROL_32BD_ENABLE 0x00000020 /* D: 32-bit addressing */
#ifndef _ALIGN_TEXT
# define _ALIGN_TEXT .align 0
#endif
/*
* gas/arm uses @ as a single comment character and thus cannot be used here
* Instead it recognised the # instead of an @ symbols in .type directives
* We define a couple of macros so that assembly code will not be dependant
* on one or the other.
*/
#define _ASM_TYPE_FUNCTION #function
#define _ASM_TYPE_OBJECT #object
#define GLOBAL(X) .globl x
#define _ENTRY(x) \
.text; _ALIGN_TEXT; .globl x; .type x,_ASM_TYPE_FUNCTION; x:
#ifdef GPROF
# ifdef __ELF__
# define _PROF_PROLOGUE \
mov ip, lr; bl __mcount
# else
# define _PROF_PROLOGUE \
mov ip,lr; bl mcount
# endif
#else
# define _PROF_PROLOGUE
#endif
#define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
#define ENTRY_NP(y) _ENTRY(_C_LABEL(y))
#define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
#define ASENTRY_NP(y) _ENTRY(_ASM_LABEL(y))
#define ASMSTR .asciz
#if defined(__ELF__) && defined(PIC)
#ifdef __STDC__
#define PIC_SYM(x,y) x ## ( ## y ## )
#else
#define PIC_SYM(x,y) x/**/(/**/y/**/)
#endif
#else
#define PIC_SYM(x,y) x
#endif
#undef __FBSDID
#if !defined(lint) && !defined(STRIP_FBSDID)
#define __FBSDID(s) .ident s
#else
#define __FBSDID(s) /* nothing */
#endif
#ifdef __ELF__
#define WEAK_ALIAS(alias,sym) \
.weak alias; \
alias = sym
#endif
#ifdef __STDC__
#define WARN_REFERENCES(sym,msg) \
.stabs msg ## ,30,0,0,0 ; \
.stabs __STRING(_C_LABEL(sym)) ## ,1,0,0,0
#elif defined(__ELF__)
#define WARN_REFERENCES(sym,msg) \
.stabs msg,30,0,0,0 ; \
.stabs __STRING(sym),1,0,0,0
#else
#define WARN_REFERENCES(sym,msg) \
.stabs msg,30,0,0,0 ; \
.stabs __STRING(_/**/sym),1,0,0,0
#endif /* __STDC__ */
#endif /* !_MACHINE_ASM_H_ */

204
sys/arm/include/asmacros.h Normal file
View File

@ -0,0 +1,204 @@
/* $NetBSD: frame.h,v 1.6 2003/10/05 19:44:58 matt Exp $ */
/*
* Copyright (c) 1994-1997 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_ASMACROS_H_
#define _MACHINE_ASMACROS_H_
#ifdef _KERNEL
#ifdef LOCORE
/*
* ASM macros for pushing and pulling trapframes from the stack
*
* These macros are used to handle the irqframe and trapframe structures
* defined above.
*/
/*
* PUSHFRAME - macro to push a trap frame on the stack in the current mode
* Since the current mode is used, the SVC lr field is not defined.
*
* NOTE: r13 and r14 are stored separately as a work around for the
* SA110 rev 2 STM^ bug
*/
#define PUSHFRAME \
str lr, [sp, #-4]!; /* Push the return address */ \
sub sp, sp, #(4*17); /* Adjust the stack pointer */ \
stmia sp, {r0-r12}; /* Push the user mode registers */ \
add r0, sp, #(4*13); /* Adjust the stack pointer */ \
stmia r0, {r13-r14}^; /* Push the user mode registers */ \
mov r0, r0; /* NOP for previous instruction */ \
mrs r0, spsr_all; /* Put the SPSR on the stack */ \
str r0, [sp, #-4]!;
/*
* PULLFRAME - macro to pull a trap frame from the stack in the current mode
* Since the current mode is used, the SVC lr field is ignored.
*/
#define PULLFRAME \
ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \
msr spsr_all, r0; \
ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
add sp, sp, #(4*17); /* Adjust the stack pointer */ \
ldr lr, [sp], #0x0004; /* Pull the return address */
/*
* PUSHFRAMEINSVC - macro to push a trap frame on the stack in SVC32 mode
* This should only be used if the processor is not currently in SVC32
* mode. The processor mode is switched to SVC mode and the trap frame is
* stored. The SVC lr field is used to store the previous value of
* lr in SVC mode.
*
* NOTE: r13 and r14 are stored separately as a work around for the
* SA110 rev 2 STM^ bug
*/
#define PUSHFRAMEINSVC \
stmdb sp, {r0-r3}; /* Save 4 registers */ \
mov r0, lr; /* Save xxx32 r14 */ \
mov r1, sp; /* Save xxx32 sp */ \
mrs r3, spsr; /* Save xxx32 spsr */ \
mrs r2, cpsr; /* Get the CPSR */ \
bic r2, r2, #(PSR_MODE); /* Fix for SVC mode */ \
orr r2, r2, #(PSR_SVC32_MODE); \
msr cpsr_c, r2; /* Punch into SVC mode */ \
mov r2, sp; /* Save SVC sp */ \
str r0, [sp, #-4]!; /* Push return address */ \
str lr, [sp, #-4]!; /* Push SVC lr */ \
str r2, [sp, #-4]!; /* Push SVC sp */ \
msr spsr_all, r3; /* Restore correct spsr */ \
ldmdb r1, {r0-r3}; /* Restore 4 regs from xxx mode */ \
sub sp, sp, #(4*15); /* Adjust the stack pointer */ \
stmia sp, {r0-r12}; /* Push the user mode registers */ \
add r0, sp, #(4*13); /* Adjust the stack pointer */ \
stmia r0, {r13-r14}^; /* Push the user mode registers */ \
mov r0, r0; /* NOP for previous instruction */ \
mrs r0, spsr_all; /* Put the SPSR on the stack */ \
str r0, [sp, #-4]!
/*
* PULLFRAMEFROMSVCANDEXIT - macro to pull a trap frame from the stack
* in SVC32 mode and restore the saved processor mode and PC.
* This should be used when the SVC lr register needs to be restored on
* exit.
*/
#define PULLFRAMEFROMSVCANDEXIT \
ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \
msr spsr_all, r0; /* restore SPSR */ \
ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
add sp, sp, #(4*15); /* Adjust the stack pointer */ \
ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */
#define DATA(name) \
.data ; \
_ALIGN_DATA ; \
.globl name ; \
.type name, %object ; \
name:
#define EMPTY
#define GET_CURPCB_ENTER \
ldr r1, .Laflt_curpcb ;\
ldr r1, [r1]
/*
* This macro must be invoked following PUSHFRAMEINSVC or PUSHFRAME at
* the top of interrupt/exception handlers.
*
* When invoked, r0 *must* contain the value of SPSR on the current
* trap/interrupt frame. This is always the case if ENABLE_ALIGNMENT_FAULTS
* is invoked immediately after PUSHFRAMEINSVC or PUSHFRAME.
*/
#define ENABLE_ALIGNMENT_FAULTS \
and r0, r0, #(PSR_MODE) /* Test for USR32 mode */ ;\
teq r0, #(PSR_USR32_MODE) ;\
bne 1f /* Not USR mode skip AFLT */ ;\
GET_CURPCB_ENTER /* r1 = curpcb */ ;\
cmp r1, #0x00 /* curpcb NULL? */ ;\
ldrne r1, [r1, #PCB_FLAGS] /* Fetch curpcb->pcb_flags */ ;\
tstne r1, #PCB_NOALIGNFLT ;\
beq 1f /* AFLTs already enabled */ ;\
ldr r2, .Laflt_cpufuncs ;\
mov lr, pc ;\
ldr pc, [r2, #CF_CONTROL] /* Enable alignment faults */ ;\
1:
#define DO_AST_AND_RESTORE_ALIGNMENT_FAULTS \
ldr r0, [sp] /* Get the SPSR from stack */ ;\
mrs r4, cpsr /* save CPSR */ ;\
and r0, r0, #(PSR_MODE) /* Returning to USR mode? */ ;\
teq r0, #(PSR_USR32_MODE) ;\
bne 2f /* Nope, get out now */ ;\
bic r4, r4, #(I32_bit) ;\
1: orr r0, r4, #(I32_bit) /* Disable IRQs */ ;\
msr cpsr_c, r0 ;\
ldr r5, .Laflt_curthread ;\
ldr r5, [r5] ;\
ldr r5, [r5, #(TD_FLAGS)] ;\
and r5, r5, #(TDF_ASTPENDING) ;\
teq r5, #0x00000000 ;\
beq 2f /* Nope. Just bail */ ;\
msr cpsr_c, r4 /* Restore interrupts */ ;\
mov r0, sp ;\
adr lr, 1b ;\
b _C_LABEL(ast) /* ast(frame) */ ;\
2:
#define AST_ALIGNMENT_FAULT_LOCALS ;\
.Laflt_curpcb: ;\
.word _C_LABEL(__pcpu) + PC_CURPCB ;\
.Laflt_cpufuncs: ;\
.word _C_LABEL(cpufuncs) ;\
.Laflt_curthread: ;\
.word _C_LABEL(__pcpu) + PC_CURTHREAD
#endif /* LOCORE */
#endif /* _KERNEL */
#endif /* !_MACHINE_ASMACROS_H_ */

197
sys/arm/include/atomic.h Normal file
View File

@ -0,0 +1,197 @@
/* $NetBSD: atomic.h,v 1.1 2002/10/19 12:22:34 bsh Exp $ */
/*
* Copyright (C) 2003-2004 Olivier Houchard
* Copyright (C) 1994-1997 Mark Brinicombe
* Copyright (C) 1994 Brini
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of Brini may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
#ifndef _LOCORE
#include <sys/types.h>
#ifndef I32_bit
#define I32_bit (1 << 7) /* IRQ disable */
#endif
#ifndef F32_bit
#define F32_bit (1 << 6) /* FIQ disable */
#endif
#define __with_interrupts_disabled(expr) \
do { \
u_int cpsr_save, tmp; \
\
__asm __volatile( \
"mrs %0, cpsr;" \
"orr %1, %0, %2;" \
"msr cpsr_all, %1;" \
: "=r" (cpsr_save), "=r" (tmp) \
: "I" (I32_bit) \
: "cc" ); \
(expr); \
__asm __volatile( \
"msr cpsr_all, %0" \
: /* no output */ \
: "r" (cpsr_save) \
: "cc" ); \
} while(0)
static __inline void
atomic_set_32(volatile uint32_t *address, uint32_t setmask)
{
__with_interrupts_disabled( *address |= setmask);
}
static __inline void
atomic_set_ptr(volatile void *ptr, uint32_t src)
{
atomic_set_32((volatile uint32_t *)ptr, (uint32_t)src);
}
#define atomic_set_rel_int atomic_set_32
#define atomic_set_int atomic_set_32
#define atomic_readandclear_int atomic_readandclear_32
static __inline void
atomic_clear_32(volatile uint32_t *address, uint32_t clearmask)
{
__with_interrupts_disabled( *address &= ~clearmask);
}
static __inline void
atomic_clear_ptr(volatile void *ptr, uint32_t src)
{
atomic_clear_32((volatile uint32_t *)ptr, (uint32_t)src);
}
static __inline int
atomic_load_acq_int(volatile uint32_t *v)
{
int bla;
__with_interrupts_disabled(bla = *v);
return (bla);
}
#define atomic_clear_int atomic_clear_32
static __inline void
atomic_store_32(volatile uint32_t *dst, uint32_t src)
{
__with_interrupts_disabled(*dst = src);
}
static __inline void
atomic_store_ptr(volatile void *dst, void *src)
{
atomic_store_32((volatile uint32_t *)dst, (uint32_t) src);
}
#define atomic_store_rel_ptr atomic_store_ptr
#define atomic_store_rel_int atomic_store_32
static __inline uint32_t
atomic_readandclear_32(volatile u_int32_t *p)
{
uint32_t ret;
__with_interrupts_disabled((ret = *p) != 0 ? *p = 0 : 0);
return (ret);
}
static __inline u_int32_t
atomic_cmpset_32(volatile u_int32_t *p, u_int32_t cmpval, u_int32_t newval)
{
int done = 0;
__with_interrupts_disabled(*p = (*p == cmpval ? newval + done++ : *p));
return (done);
}
static __inline void
atomic_add_32(volatile u_int32_t *p, u_int32_t val)
{
__with_interrupts_disabled(*p += val);
}
static __inline void
atomic_subtract_32(volatile u_int32_t *p, u_int32_t val)
{
__with_interrupts_disabled(*p -= val);
}
#define atomic_subtract_int atomic_subtract_32
#define atomic_subtract_rel_int atomic_subtract_32
#define atomic_subtract_acq_int atomic_subtract_32
#define atomic_add_int atomic_add_32
#define atomic_add_rel_int atomic_add_32
#define atomic_add_acq_int atomic_add_32
#define atomic_cmpset_int atomic_cmpset_32
#define atomic_cmpset_rel_int atomic_cmpset_32
#define atomic_cmpset_acq_int atomic_cmpset_32
static __inline u_int32_t
atomic_cmpset_ptr(volatile void *dst, void *exp, void *src)
{
return (atomic_cmpset_32((volatile u_int32_t *)dst, (u_int32_t)exp,
(u_int32_t)src));
}
static __inline u_int32_t
atomic_cmpset_rel_32(volatile u_int32_t *p, u_int32_t cmpval, u_int32_t newval)
{
return (atomic_cmpset_32(p, cmpval, newval));
}
static __inline u_int32_t
atomic_cmpset_rel_ptr(volatile void *dst, void *exp, void *src)
{
return (atomic_cmpset_32((volatile u_int32_t *)dst,
(u_int32_t)exp, (u_int32_t)src));
}
#define atomic_cmpset_acq_ptr atomic_cmpset_ptr
#if !defined(ATOMIC_SET_BIT_NOINLINE)
#define atomic_set_bit(a,m) atomic_set_32(a,m)
#define atomic_clear_bit(a,m) atomic_clear_32(a,m)
#endif
#undef __with_interrupts_disabled
#endif /* _LOCORE */
#endif /* _MACHINE_ATOMIC_H_ */

56
sys/arm/include/blockio.h Normal file
View File

@ -0,0 +1,56 @@
/* $NetBSD: blockio.h,v 1.2 2001/06/02 10:44:56 bjh21 Exp $ */
/*-
* Copyright (c) 2001 Ben Harris
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*
*/
/*
* blockio.h - low level functions for bulk PIO data transfer
*/
#ifndef _MACHINE_BLOCKIO_H_
#define _MACHINE_BLOCKIO_H_
/*
* All these take three arguments:
* I/O address
* Memory address
* Number of bytes to copy
*/
void read_multi_1(u_int, void *, u_int);
void write_multi_1(u_int, const void *, u_int);
#define read_multi_2 insw16
#define write_multi_2 outsw16
void insw(u_int, void *, u_int);
void outsw(u_int, void *, u_int);
void insw16(u_int, void *, u_int);
void outsw16(u_int, void *, u_int);
#endif /* !_MACHINE_BLOCKIO_H_ */

View File

@ -0,0 +1,58 @@
/* $NetBSD: bootconfig.h,v 1.1 2001/05/13 13:46:23 bjh21 Exp $ */
/*
* Copyright (c) 1994 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe
* for the NetBSD Project.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_BOOTCONFIG_H_
#define _MACHINE_BOOTCONFIG_H_
#ifdef _KERNEL
#define BOOTOPT_TYPE_BOOLEAN 0
#define BOOTOPT_TYPE_STRING 1
#define BOOTOPT_TYPE_INT 2
#define BOOTOPT_TYPE_BININT 3
#define BOOTOPT_TYPE_HEXINT 4
#define BOOTOPT_TYPE_MASK 7
int get_bootconf_option __P((char *, char *, int, void *));
extern char *boot_args;
extern char *boot_file;
#endif /* _KERNEL */
#endif /* !_MACHINE_BOOTCONFIG_H_ */

769
sys/arm/include/bus.h Normal file
View File

@ -0,0 +1,769 @@
/* $NetBSD: bus.h,v 1.11 2003/07/28 17:35:54 thorpej Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1996 Charles M. Hannum. All rights reserved.
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christopher G. Demetriou
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_BUS_H_
#define _MACHINE_BUS_H_
/*
* Addresses (in bus space).
*/
typedef u_long bus_addr_t;
typedef u_long bus_size_t;
/*
* Access methods for bus space.
*/
typedef struct bus_space *bus_space_tag_t;
typedef u_long bus_space_handle_t;
/*
* int bus_space_map (bus_space_tag_t t, bus_addr_t addr,
* bus_size_t size, int flags, bus_space_handle_t *bshp);
*
* Map a region of bus space.
*/
#define BUS_SPACE_MAP_CACHEABLE 0x01
#define BUS_SPACE_MAP_LINEAR 0x02
#define BUS_SPACE_MAP_PREFETCHABLE 0x04
struct bus_space {
/* cookie */
void *bs_cookie;
/* mapping/unmapping */
int (*bs_map) (void *, bus_addr_t, bus_size_t,
int, bus_space_handle_t *);
void (*bs_unmap) (void *, bus_size_t);
int (*bs_subregion) (void *, bus_space_handle_t,
bus_size_t, bus_size_t, bus_space_handle_t *);
/* allocation/deallocation */
int (*bs_alloc) (void *, bus_addr_t, bus_addr_t,
bus_size_t, bus_size_t, bus_size_t, int,
bus_addr_t *, bus_space_handle_t *);
void (*bs_free) (void *, bus_space_handle_t,
bus_size_t);
/* get kernel virtual address */
void * (*bs_vaddr) (void *, bus_space_handle_t);
/* mmap bus space for user */
int (*bs_mmap) (dev_t, vm_offset_t, vm_paddr_t *, int);
/* barrier */
void (*bs_barrier) (void *, bus_space_handle_t,
bus_size_t, bus_size_t, int);
/* read (single) */
u_int8_t (*bs_r_1) (void *, bus_space_handle_t, bus_size_t);
u_int16_t (*bs_r_2) (void *, bus_space_handle_t, bus_size_t);
u_int32_t (*bs_r_4) (void *, bus_space_handle_t, bus_size_t);
u_int64_t (*bs_r_8) (void *, bus_space_handle_t, bus_size_t);
/* read multiple */
void (*bs_rm_1) (void *, bus_space_handle_t, bus_size_t,
u_int8_t *, bus_size_t);
void (*bs_rm_2) (void *, bus_space_handle_t, bus_size_t,
u_int16_t *, bus_size_t);
void (*bs_rm_4) (void *, bus_space_handle_t,
bus_size_t, u_int32_t *, bus_size_t);
void (*bs_rm_8) (void *, bus_space_handle_t,
bus_size_t, u_int64_t *, bus_size_t);
/* read region */
void (*bs_rr_1) (void *, bus_space_handle_t,
bus_size_t, u_int8_t *, bus_size_t);
void (*bs_rr_2) (void *, bus_space_handle_t,
bus_size_t, u_int16_t *, bus_size_t);
void (*bs_rr_4) (void *, bus_space_handle_t,
bus_size_t, u_int32_t *, bus_size_t);
void (*bs_rr_8) (void *, bus_space_handle_t,
bus_size_t, u_int64_t *, bus_size_t);
/* write (single) */
void (*bs_w_1) (void *, bus_space_handle_t,
bus_size_t, u_int8_t);
void (*bs_w_2) (void *, bus_space_handle_t,
bus_size_t, u_int16_t);
void (*bs_w_4) (void *, bus_space_handle_t,
bus_size_t, u_int32_t);
void (*bs_w_8) (void *, bus_space_handle_t,
bus_size_t, u_int64_t);
/* write multiple */
void (*bs_wm_1) (void *, bus_space_handle_t,
bus_size_t, const u_int8_t *, bus_size_t);
void (*bs_wm_2) (void *, bus_space_handle_t,
bus_size_t, const u_int16_t *, bus_size_t);
void (*bs_wm_4) (void *, bus_space_handle_t,
bus_size_t, const u_int32_t *, bus_size_t);
void (*bs_wm_8) (void *, bus_space_handle_t,
bus_size_t, const u_int64_t *, bus_size_t);
/* write region */
void (*bs_wr_1) (void *, bus_space_handle_t,
bus_size_t, const u_int8_t *, bus_size_t);
void (*bs_wr_2) (void *, bus_space_handle_t,
bus_size_t, const u_int16_t *, bus_size_t);
void (*bs_wr_4) (void *, bus_space_handle_t,
bus_size_t, const u_int32_t *, bus_size_t);
void (*bs_wr_8) (void *, bus_space_handle_t,
bus_size_t, const u_int64_t *, bus_size_t);
/* set multiple */
void (*bs_sm_1) (void *, bus_space_handle_t,
bus_size_t, u_int8_t, bus_size_t);
void (*bs_sm_2) (void *, bus_space_handle_t,
bus_size_t, u_int16_t, bus_size_t);
void (*bs_sm_4) (void *, bus_space_handle_t,
bus_size_t, u_int32_t, bus_size_t);
void (*bs_sm_8) (void *, bus_space_handle_t,
bus_size_t, u_int64_t, bus_size_t);
/* set region */
void (*bs_sr_1) (void *, bus_space_handle_t,
bus_size_t, u_int8_t, bus_size_t);
void (*bs_sr_2) (void *, bus_space_handle_t,
bus_size_t, u_int16_t, bus_size_t);
void (*bs_sr_4) (void *, bus_space_handle_t,
bus_size_t, u_int32_t, bus_size_t);
void (*bs_sr_8) (void *, bus_space_handle_t,
bus_size_t, u_int64_t, bus_size_t);
/* copy */
void (*bs_c_1) (void *, bus_space_handle_t, bus_size_t,
bus_space_handle_t, bus_size_t, bus_size_t);
void (*bs_c_2) (void *, bus_space_handle_t, bus_size_t,
bus_space_handle_t, bus_size_t, bus_size_t);
void (*bs_c_4) (void *, bus_space_handle_t, bus_size_t,
bus_space_handle_t, bus_size_t, bus_size_t);
void (*bs_c_8) (void *, bus_space_handle_t, bus_size_t,
bus_space_handle_t, bus_size_t, bus_size_t);
};
/*
* Utility macros; INTERNAL USE ONLY.
*/
#define __bs_c(a,b) __CONCAT(a,b)
#define __bs_opname(op,size) __bs_c(__bs_c(__bs_c(bs_,op),_),size)
#define __bs_rs(sz, t, h, o) \
(*(t)->__bs_opname(r,sz))((t)->bs_cookie, h, o)
#define __bs_ws(sz, t, h, o, v) \
(*(t)->__bs_opname(w,sz))((t)->bs_cookie, h, o, v)
#define __bs_nonsingle(type, sz, t, h, o, a, c) \
(*(t)->__bs_opname(type,sz))((t)->bs_cookie, h, o, a, c)
#define __bs_set(type, sz, t, h, o, v, c) \
(*(t)->__bs_opname(type,sz))((t)->bs_cookie, h, o, v, c)
#define __bs_copy(sz, t, h1, o1, h2, o2, cnt) \
(*(t)->__bs_opname(c,sz))((t)->bs_cookie, h1, o1, h2, o2, cnt)
/*
* Mapping and unmapping operations.
*/
#define bus_space_map(t, a, s, c, hp) \
(*(t)->bs_map)((t)->bs_cookie, (a), (s), (c), (hp))
#define bus_space_unmap(t, h, s) \
(*(t)->bs_unmap)((t)->bs_cookie, (h), (s))
#define bus_space_subregion(t, h, o, s, hp) \
(*(t)->bs_subregion)((t)->bs_cookie, (h), (o), (s), (hp))
/*
* Allocation and deallocation operations.
*/
#define bus_space_alloc(t, rs, re, s, a, b, c, ap, hp) \
(*(t)->bs_alloc)((t)->bs_cookie, (rs), (re), (s), (a), (b), \
(c), (ap), (hp))
#define bus_space_free(t, h, s) \
(*(t)->bs_free)((t)->bs_cookie, (h), (s))
/*
* Get kernel virtual address for ranges mapped BUS_SPACE_MAP_LINEAR.
*/
#define bus_space_vaddr(t, h) \
(*(t)->bs_vaddr)((t)->bs_cookie, (h))
/*
* MMap bus space for a user application.
*/
#define bus_space_mmap(t, a, o, p, f) \
(*(t)->bs_mmap)((t)->bs_cookie, (a), (o), (p), (f))
/*
* Bus barrier operations.
*/
#define bus_space_barrier(t, h, o, l, f) \
(*(t)->bs_barrier)((t)->bs_cookie, (h), (o), (l), (f))
#define BUS_SPACE_BARRIER_READ 0x01
#define BUS_SPACE_BARRIER_WRITE 0x02
/*
* Bus read (single) operations.
*/
#define bus_space_read_1(t, h, o) __bs_rs(1,(t),(h),(o))
#define bus_space_read_2(t, h, o) __bs_rs(2,(t),(h),(o))
#define bus_space_read_4(t, h, o) __bs_rs(4,(t),(h),(o))
#define bus_space_read_8(t, h, o) __bs_rs(8,(t),(h),(o))
/*
* Bus read multiple operations.
*/
#define bus_space_read_multi_1(t, h, o, a, c) \
__bs_nonsingle(rm,1,(t),(h),(o),(a),(c))
#define bus_space_read_multi_2(t, h, o, a, c) \
__bs_nonsingle(rm,2,(t),(h),(o),(a),(c))
#define bus_space_read_multi_4(t, h, o, a, c) \
__bs_nonsingle(rm,4,(t),(h),(o),(a),(c))
#define bus_space_read_multi_8(t, h, o, a, c) \
__bs_nonsingle(rm,8,(t),(h),(o),(a),(c))
/*
* Bus read region operations.
*/
#define bus_space_read_region_1(t, h, o, a, c) \
__bs_nonsingle(rr,1,(t),(h),(o),(a),(c))
#define bus_space_read_region_2(t, h, o, a, c) \
__bs_nonsingle(rr,2,(t),(h),(o),(a),(c))
#define bus_space_read_region_4(t, h, o, a, c) \
__bs_nonsingle(rr,4,(t),(h),(o),(a),(c))
#define bus_space_read_region_8(t, h, o, a, c) \
__bs_nonsingle(rr,8,(t),(h),(o),(a),(c))
/*
* Bus write (single) operations.
*/
#define bus_space_write_1(t, h, o, v) __bs_ws(1,(t),(h),(o),(v))
#define bus_space_write_2(t, h, o, v) __bs_ws(2,(t),(h),(o),(v))
#define bus_space_write_4(t, h, o, v) __bs_ws(4,(t),(h),(o),(v))
#define bus_space_write_8(t, h, o, v) __bs_ws(8,(t),(h),(o),(v))
/*
* Bus write multiple operations.
*/
#define bus_space_write_multi_1(t, h, o, a, c) \
__bs_nonsingle(wm,1,(t),(h),(o),(a),(c))
#define bus_space_write_multi_2(t, h, o, a, c) \
__bs_nonsingle(wm,2,(t),(h),(o),(a),(c))
#define bus_space_write_multi_4(t, h, o, a, c) \
__bs_nonsingle(wm,4,(t),(h),(o),(a),(c))
#define bus_space_write_multi_8(t, h, o, a, c) \
__bs_nonsingle(wm,8,(t),(h),(o),(a),(c))
/*
* Bus write region operations.
*/
#define bus_space_write_region_1(t, h, o, a, c) \
__bs_nonsingle(wr,1,(t),(h),(o),(a),(c))
#define bus_space_write_region_2(t, h, o, a, c) \
__bs_nonsingle(wr,2,(t),(h),(o),(a),(c))
#define bus_space_write_region_4(t, h, o, a, c) \
__bs_nonsingle(wr,4,(t),(h),(o),(a),(c))
#define bus_space_write_region_8(t, h, o, a, c) \
__bs_nonsingle(wr,8,(t),(h),(o),(a),(c))
/*
* Set multiple operations.
*/
#define bus_space_set_multi_1(t, h, o, v, c) \
__bs_set(sm,1,(t),(h),(o),(v),(c))
#define bus_space_set_multi_2(t, h, o, v, c) \
__bs_set(sm,2,(t),(h),(o),(v),(c))
#define bus_space_set_multi_4(t, h, o, v, c) \
__bs_set(sm,4,(t),(h),(o),(v),(c))
#define bus_space_set_multi_8(t, h, o, v, c) \
__bs_set(sm,8,(t),(h),(o),(v),(c))
/*
* Set region operations.
*/
#define bus_space_set_region_1(t, h, o, v, c) \
__bs_set(sr,1,(t),(h),(o),(v),(c))
#define bus_space_set_region_2(t, h, o, v, c) \
__bs_set(sr,2,(t),(h),(o),(v),(c))
#define bus_space_set_region_4(t, h, o, v, c) \
__bs_set(sr,4,(t),(h),(o),(v),(c))
#define bus_space_set_region_8(t, h, o, v, c) \
__bs_set(sr,8,(t),(h),(o),(v),(c))
/*
* Copy operations.
*/
#define bus_space_copy_region_1(t, h1, o1, h2, o2, c) \
__bs_copy(1, t, h1, o1, h2, o2, c)
#define bus_space_copy_region_2(t, h1, o1, h2, o2, c) \
__bs_copy(2, t, h1, o1, h2, o2, c)
#define bus_space_copy_region_4(t, h1, o1, h2, o2, c) \
__bs_copy(4, t, h1, o1, h2, o2, c)
#define bus_space_copy_region_8(t, h1, o1, h2, o2, c) \
__bs_copy(8, t, h1, o1, h2, o2, c)
/*
* Macros to provide prototypes for all the functions used in the
* bus_space structure
*/
#define bs_map_proto(f) \
int __bs_c(f,_bs_map) (void *t, bus_addr_t addr, \
bus_size_t size, int cacheable, bus_space_handle_t *bshp);
#define bs_unmap_proto(f) \
void __bs_c(f,_bs_unmap) (void *t, bus_size_t size);
#define bs_subregion_proto(f) \
int __bs_c(f,_bs_subregion) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, bus_size_t size, \
bus_space_handle_t *nbshp);
#define bs_alloc_proto(f) \
int __bs_c(f,_bs_alloc) (void *t, bus_addr_t rstart, \
bus_addr_t rend, bus_size_t size, bus_size_t align, \
bus_size_t boundary, int cacheable, bus_addr_t *addrp, \
bus_space_handle_t *bshp);
#define bs_free_proto(f) \
void __bs_c(f,_bs_free) (void *t, bus_space_handle_t bsh, \
bus_size_t size);
#define bs_vaddr_proto(f) \
void * __bs_c(f,_bs_vaddr) (void *t, bus_space_handle_t bsh);
#define bs_mmap_proto(f) \
int __bs_c(f,_bs_mmap) (dev_t, vm_offset_t, vm_paddr_t *, int);
#define bs_barrier_proto(f) \
void __bs_c(f,_bs_barrier) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, bus_size_t len, int flags);
#define bs_r_1_proto(f) \
u_int8_t __bs_c(f,_bs_r_1) (void *t, bus_space_handle_t bsh, \
bus_size_t offset);
#define bs_r_2_proto(f) \
u_int16_t __bs_c(f,_bs_r_2) (void *t, bus_space_handle_t bsh, \
bus_size_t offset);
#define bs_r_4_proto(f) \
u_int32_t __bs_c(f,_bs_r_4) (void *t, bus_space_handle_t bsh, \
bus_size_t offset);
#define bs_r_8_proto(f) \
u_int64_t __bs_c(f,_bs_r_8) (void *t, bus_space_handle_t bsh, \
bus_size_t offset);
#define bs_w_1_proto(f) \
void __bs_c(f,_bs_w_1) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int8_t value);
#define bs_w_2_proto(f) \
void __bs_c(f,_bs_w_2) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int16_t value);
#define bs_w_4_proto(f) \
void __bs_c(f,_bs_w_4) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int32_t value);
#define bs_w_8_proto(f) \
void __bs_c(f,_bs_w_8) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int64_t value);
#define bs_rm_1_proto(f) \
void __bs_c(f,_bs_rm_1) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int8_t *addr, bus_size_t count);
#define bs_rm_2_proto(f) \
void __bs_c(f,_bs_rm_2) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int16_t *addr, bus_size_t count);
#define bs_rm_4_proto(f) \
void __bs_c(f,_bs_rm_4) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int32_t *addr, bus_size_t count);
#define bs_rm_8_proto(f) \
void __bs_c(f,_bs_rm_8) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int64_t *addr, bus_size_t count);
#define bs_wm_1_proto(f) \
void __bs_c(f,_bs_wm_1) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, const u_int8_t *addr, bus_size_t count);
#define bs_wm_2_proto(f) \
void __bs_c(f,_bs_wm_2) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, const u_int16_t *addr, bus_size_t count);
#define bs_wm_4_proto(f) \
void __bs_c(f,_bs_wm_4) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, const u_int32_t *addr, bus_size_t count);
#define bs_wm_8_proto(f) \
void __bs_c(f,_bs_wm_8) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, const u_int64_t *addr, bus_size_t count);
#define bs_rr_1_proto(f) \
void __bs_c(f, _bs_rr_1) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int8_t *addr, bus_size_t count);
#define bs_rr_2_proto(f) \
void __bs_c(f, _bs_rr_2) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int16_t *addr, bus_size_t count);
#define bs_rr_4_proto(f) \
void __bs_c(f, _bs_rr_4) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int32_t *addr, bus_size_t count);
#define bs_rr_8_proto(f) \
void __bs_c(f, _bs_rr_8) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int64_t *addr, bus_size_t count);
#define bs_wr_1_proto(f) \
void __bs_c(f, _bs_wr_1) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, const u_int8_t *addr, bus_size_t count);
#define bs_wr_2_proto(f) \
void __bs_c(f, _bs_wr_2) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, const u_int16_t *addr, bus_size_t count);
#define bs_wr_4_proto(f) \
void __bs_c(f, _bs_wr_4) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, const u_int32_t *addr, bus_size_t count);
#define bs_wr_8_proto(f) \
void __bs_c(f, _bs_wr_8) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, const u_int64_t *addr, bus_size_t count);
#define bs_sm_1_proto(f) \
void __bs_c(f,_bs_sm_1) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int8_t value, bus_size_t count);
#define bs_sm_2_proto(f) \
void __bs_c(f,_bs_sm_2) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int16_t value, bus_size_t count);
#define bs_sm_4_proto(f) \
void __bs_c(f,_bs_sm_4) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int32_t value, bus_size_t count);
#define bs_sm_8_proto(f) \
void __bs_c(f,_bs_sm_8) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int64_t value, bus_size_t count);
#define bs_sr_1_proto(f) \
void __bs_c(f,_bs_sr_1) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int8_t value, bus_size_t count);
#define bs_sr_2_proto(f) \
void __bs_c(f,_bs_sr_2) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int16_t value, bus_size_t count);
#define bs_sr_4_proto(f) \
void __bs_c(f,_bs_sr_4) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int32_t value, bus_size_t count);
#define bs_sr_8_proto(f) \
void __bs_c(f,_bs_sr_8) (void *t, bus_space_handle_t bsh, \
bus_size_t offset, u_int64_t value, bus_size_t count);
#define bs_c_1_proto(f) \
void __bs_c(f,_bs_c_1) (void *t, bus_space_handle_t bsh1, \
bus_size_t offset1, bus_space_handle_t bsh2, \
bus_size_t offset2, bus_size_t count);
#define bs_c_2_proto(f) \
void __bs_c(f,_bs_c_2) (void *t, bus_space_handle_t bsh1, \
bus_size_t offset1, bus_space_handle_t bsh2, \
bus_size_t offset2, bus_size_t count);
#define bs_c_4_proto(f) \
void __bs_c(f,_bs_c_4) (void *t, bus_space_handle_t bsh1, \
bus_size_t offset1, bus_space_handle_t bsh2, \
bus_size_t offset2, bus_size_t count);
#define bs_c_8_proto(f) \
void __bs_c(f,_bs_c_8) (void *t, bus_space_handle_t bsh1, \
bus_size_t offset1, bus_space_handle_t bsh2, \
bus_size_t offset2, bus_size_t count);
#define bs_protos(f) \
bs_map_proto(f); \
bs_unmap_proto(f); \
bs_subregion_proto(f); \
bs_alloc_proto(f); \
bs_free_proto(f); \
bs_vaddr_proto(f); \
bs_mmap_proto(f); \
bs_barrier_proto(f); \
bs_r_1_proto(f); \
bs_r_2_proto(f); \
bs_r_4_proto(f); \
bs_r_8_proto(f); \
bs_w_1_proto(f); \
bs_w_2_proto(f); \
bs_w_4_proto(f); \
bs_w_8_proto(f); \
bs_rm_1_proto(f); \
bs_rm_2_proto(f); \
bs_rm_4_proto(f); \
bs_rm_8_proto(f); \
bs_wm_1_proto(f); \
bs_wm_2_proto(f); \
bs_wm_4_proto(f); \
bs_wm_8_proto(f); \
bs_rr_1_proto(f); \
bs_rr_2_proto(f); \
bs_rr_4_proto(f); \
bs_rr_8_proto(f); \
bs_wr_1_proto(f); \
bs_wr_2_proto(f); \
bs_wr_4_proto(f); \
bs_wr_8_proto(f); \
bs_sm_1_proto(f); \
bs_sm_2_proto(f); \
bs_sm_4_proto(f); \
bs_sm_8_proto(f); \
bs_sr_1_proto(f); \
bs_sr_2_proto(f); \
bs_sr_4_proto(f); \
bs_sr_8_proto(f); \
bs_c_1_proto(f); \
bs_c_2_proto(f); \
bs_c_4_proto(f); \
bs_c_8_proto(f);
#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
/* Bus Space DMA macros */
/*
* Flags used in various bus DMA methods.
*/
#define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */
#define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */
#define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */
#define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */
#define BUS_DMA_ZERO 0x008 /* hint: sequential, unidirectional */
#define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */
#define BUS_DMA_BUS2 0x020
#define BUS_DMA_BUS3 0x040
#define BUS_DMA_BUS4 0x080
/*
* Private flags stored in the DMA map.
*/
#define ARM32_DMAMAP_COHERENT 0x10000 /* no cache flush necessary on sync */
/* Forwards needed by prototypes below. */
struct mbuf;
struct uio;
/*
* Operations performed by bus_dmamap_sync().
*/
#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
typedef struct bus_dma_tag *bus_dma_tag_t;
typedef struct bus_dmamap *bus_dmamap_t;
#define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0)
/*
* bus_dma_segment_t
*
* Describes a single contiguous DMA transaction. Values
* are suitable for programming into DMA registers.
*/
struct bus_dma_segment {
/*
* PUBLIC MEMBERS: these are used by machine-independent code.
*/
bus_addr_t ds_addr; /* DMA address */
bus_size_t ds_len; /* length of transfer */
};
typedef struct bus_dma_segment bus_dma_segment_t;
/*
* arm32_dma_range
*
* This structure describes a valid DMA range.
*/
struct arm32_dma_range {
bus_addr_t dr_sysbase; /* system base address */
bus_addr_t dr_busbase; /* appears here on bus */
bus_size_t dr_len; /* length of range */
};
/*
* bus_dma_tag_t
*
* A machine-dependent opaque type describing the implementation of
* DMA for a given bus.
*/
typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
typedef int bus_dmasync_op_t;
typedef void bus_dmamap_callback2_t(void *, bus_dma_segment_t *, int, bus_size_t, int);
#ifdef _ARM32_BUS_DMA_PRIVATE
/* _dm_buftype */
#define ARM32_BUFTYPE_INVALID 0
#define ARM32_BUFTYPE_LINEAR 1
#define ARM32_BUFTYPE_MBUF 2
#define ARM32_BUFTYPE_UIO 3
#define ARM32_BUFTYPE_RAW 4
struct arm32_dma_range *bus_dma_get_range(void);
#endif /* _ARM32_BUS_DMA_PRIVATE */
/*
* A function that returns 1 if the address cannot be accessed by
* a device and 0 if it can be.
*/
typedef int bus_dma_filter_t(void *, bus_addr_t);
/*
* A function that performs driver-specific syncronization on behalf of
* busdma.
*/
typedef enum {
BUS_DMA_LOCK = 0x01,
BUS_DMA_UNLOCK = 0x02,
} bus_dma_lock_op_t;
typedef void bus_dma_lock_t(void *, bus_dma_lock_op_t);
/*
* Allocate a device specific dma_tag encapsulating the constraints of
* the parent tag in addition to other restrictions specified:
*
* alignment: alignment for segments.
* boundary: Boundary that segments cannot cross.
* lowaddr: Low restricted address that cannot appear in a mapping.
* highaddr: High restricted address that cannot appear in a mapping.
* filtfunc: An optional function to further test if an address
* within the range of lowaddr and highaddr cannot appear
* in a mapping.
* filtfuncarg: An argument that will be passed to filtfunc in addition
* to the address to test.
* maxsize: Maximum mapping size supported by this tag.
* nsegments: Number of discontinuities allowed in maps.
* maxsegsz: Maximum size of a segment in the map.
* flags: Bus DMA flags.
* dmat: A pointer to set to a valid dma tag should the return
* value of this function indicate success.
*/
int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
bus_size_t boundary, bus_addr_t lowaddr,
bus_addr_t highaddr, bus_dma_filter_t *filtfunc,
void *filtfuncarg, bus_size_t maxsize, int nsegments,
bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
void *lockfuncarg, bus_dma_tag_t *dmat);
int bus_dma_tag_destroy(bus_dma_tag_t dmat);
int bus_dmamap_create (bus_dma_tag_t, int, bus_dmamap_t *);
int bus_dmamap_destroy (bus_dma_tag_t, bus_dmamap_t);
int bus_dmamap_load (bus_dma_tag_t, bus_dmamap_t, void *,
bus_size_t, bus_dmamap_callback_t *, void *, int);
int bus_dmamap_load_mbuf (bus_dma_tag_t, bus_dmamap_t,
struct mbuf *, bus_dmamap_callback2_t *, void *, int);
int bus_dmamap_load_uio (bus_dma_tag_t, bus_dmamap_t,
struct uio *, bus_dmamap_callback2_t *, void *, int);
void bus_dmamap_unload (bus_dma_tag_t, bus_dmamap_t);
void bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t);
int bus_dmamem_alloc (bus_dma_tag_t tag, void **vaddr, int flag,
bus_dmamap_t *mapp);
void bus_dmamem_free (bus_dma_tag_t tag, void *vaddr, bus_dmamap_t map);
/*
* Generic helper function for manipulating mutexes.
*/
void busdma_lock_mutex(void *arg, bus_dma_lock_op_t op);
#endif /* _MACHINE_BUS_H_ */

32
sys/arm/include/clock.h Normal file
View File

@ -0,0 +1,32 @@
/*-
* Copyright (c) 2004 Olivier Houchard
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_CLOCK_H_
#define _MACHINE_CLOCK_H_
#endif /* !_MACHINE_CLOCK_H_ */

49
sys/arm/include/cpu.h Normal file
View File

@ -0,0 +1,49 @@
/* $NetBSD: cpu.h,v 1.2 2001/02/23 21:23:52 reinoud Exp $ */
/* $FreeBSD$ */
#ifndef MACHINE_CPU_H
#define MACHINE_CPU_H
#include <machine/armreg.h>
void cpu_halt(void);
void swi_vm(void *);
static __inline uint64_t
get_cyclecount(void)
{
return (0);
}
#define CPU_CONSDEV 1
#define CPU_ADJKERNTZ 2 /* int: timezone offset (seconds) */
#define CPU_DISRTCSET 3 /* int: disable resettodr() call */
#define CPU_BOOTINFO 4 /* struct: bootinfo */
#define CPU_WALLCLOCK 5 /* int: indicates wall CMOS clock */
#define CPU_MAXID 6 /* number of valid machdep ids */
#define CLKF_USERMODE(frame) ((frame->if_spsr & PSR_MODE) == PSR_USR32_MODE)
#define TRAPF_USERMODE(frame) ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE)
#define CLKF_PC(frame) (frame->if_pc)
#define TRAPF_PC(tfp) ((tfp)->tf_pc)
#define cpu_getstack(td) ((td)->td_frame->tf_usr_sp)
#define cpu_setstack(td, sp) ((td)->td_frame->tf_usr_sp = (sp))
#define ARM_NVEC 8
#define ARM_VEC_ALL 0xffffffff
extern vm_offset_t vector_page;
void fork_trampoline(void);
void *initarm(void *, void *);
void arm_vector_init(vm_offset_t, int);
void identify_arm_cpu(void);
extern char btext[];
extern char etext[];
int badaddr_read (void *, size_t, void *);
#endif /* !MACHINE_CPU_H */

171
sys/arm/include/cpuconf.h Normal file
View File

@ -0,0 +1,171 @@
/* $NetBSD: cpuconf.h,v 1.8 2003/09/06 08:55:42 rearnsha Exp $ */
/*
* Copyright (c) 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*
*/
#ifndef _MACHINE_CPUCONF_H_
#define _MACHINE_CPUCONF_H_
/*
* IF YOU CHANGE THIS FILE, MAKE SURE TO UPDATE THE DEFINITION OF
* "PMAP_NEEDS_PTE_SYNC" IN <arm/arm32/pmap.h> FOR THE CPU TYPE
* YOU ARE ADDING SUPPORT FOR.
*/
/*
* Step 1: Count the number of CPU types configured into the kernel.
*/
#if defined(_KERNEL_OPT)
#define CPU_NTYPES (defined(CPU_ARM2) + defined(CPU_ARM250) + \
defined(CPU_ARM3) + \
defined(CPU_ARM6) + defined(CPU_ARM7) + \
defined(CPU_ARM7TDMI) + \
defined(CPU_ARM8) + defined(CPU_ARM9) + \
defined(CPU_ARM10) + \
defined(CPU_SA110) + defined(CPU_SA1100) + \
defined(CPU_SA1110) + \
defined(CPU_IXP12X0) + \
defined(CPU_XSCALE_80200) + \
defined(CPU_XSCALE_80321) + \
defined(CPU_XSCALE_PXA2X0) + \
defined(CPU_XSCALE_IXP425))
#else
#define CPU_NTYPES 2
#endif /* _KERNEL_OPT */
/*
* Step 2: Determine which ARM architecture versions are configured.
*/
#if !defined(_KERNEL_OPT) || \
(defined(CPU_ARM2) || defined(CPU_ARM250) || defined(CPU_ARM3))
#define ARM_ARCH_2 1
#else
#define ARM_ARCH_2 0
#endif
#if !defined(_KERNEL_OPT) || \
(defined(CPU_ARM6) || defined(CPU_ARM7))
#define ARM_ARCH_3 1
#else
#define ARM_ARCH_3 0
#endif
#if !defined(_KERNEL_OPT) || \
(defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) || \
defined(CPU_ARM10) || defined(CPU_SA110) || defined(CPU_SA1100) || \
defined(CPU_SA1110) || defined(CPU_IXP12X0) || defined(CPU_XSCALE_IXP425))
#define ARM_ARCH_4 1
#else
#define ARM_ARCH_4 0
#endif
#if !defined(_KERNEL_OPT) || \
(defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
defined(CPU_XSCALE_PXA2X0))
#define ARM_ARCH_5 1
#else
#define ARM_ARCH_5 0
#endif
#define ARM_NARCH (ARM_ARCH_2 + ARM_ARCH_3 + ARM_ARCH_4 + ARM_ARCH_5)
#if ARM_NARCH == 0
#error ARM_NARCH is 0
#endif
/*
* Step 3: Define which MMU classes are configured:
*
* ARM_MMU_MEMC Prehistoric, external memory controller
* and MMU for ARMv2 CPUs.
*
* ARM_MMU_GENERIC Generic ARM MMU, compatible with ARM6.
*
* ARM_MMU_SA1 StrongARM SA-1 MMU. Compatible with generic
* ARM MMU, but has no write-through cache mode.
*
* ARM_MMU_XSCALE XScale MMU. Compatible with generic ARM
* MMU, but also has several extensions which
* require different PTE layout to use.
*/
#if (defined(CPU_ARM2) || defined(CPU_ARM250) || defined(CPU_ARM3))
#define ARM_MMU_MEMC 1
#else
#define ARM_MMU_MEMC 0
#endif
#if (defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM7TDMI) || \
defined(CPU_ARM8) || defined(CPU_ARM9) || defined(CPU_ARM10))
#define ARM_MMU_GENERIC 1
#else
#define ARM_MMU_GENERIC 0
#endif
#if (defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) ||\
defined(CPU_IXP12X0))
#define ARM_MMU_SA1 1
#else
#define ARM_MMU_SA1 0
#endif
#if(defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425))
#define ARM_MMU_XSCALE 1
#else
#define ARM_MMU_XSCALE 0
#endif
#define ARM_NMMUS (ARM_MMU_MEMC + ARM_MMU_GENERIC + \
ARM_MMU_SA1 + ARM_MMU_XSCALE)
#if ARM_NMMUS == 0
#error ARM_NMMUS is 0
#endif
/*
* Step 4: Define features that may be present on a subset of CPUs
*
* ARM_XSCALE_PMU Performance Monitoring Unit on 80200 and 80321
*/
#if !defined(_KERNEL_OPT) || \
(defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321))
#define ARM_XSCALE_PMU 1
#else
#define ARM_XSCALE_PMU 0
#endif
#endif /* _MACHINE_CPUCONF_H_ */

530
sys/arm/include/cpufunc.h Normal file
View File

@ -0,0 +1,530 @@
/* $NetBSD: cpufunc.h,v 1.29 2003/09/06 09:08:35 rearnsha Exp $ */
/*
* Copyright (c) 1997 Mark Brinicombe.
* Copyright (c) 1997 Causality Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Causality Limited.
* 4. The name of Causality Limited may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* cpufunc.h
*
* Prototypes for cpu, mmu and tlb related functions.
*
* $FreeBSD$
*/
#ifndef _MACHINE_CPUFUNC_H_
#define _MACHINE_CPUFUNC_H_
#ifdef _KERNEL
#include <sys/types.h>
#include <machine/cpuconf.h>
void disable_intr(void);
void enable_intr(void);
static __inline register_t
intr_disable(void)
{
int s = 0, tmp;
__asm __volatile("mrs %0, cpsr; \
orr %1, %0, %2;\
msr cpsr_all, %1;"
: "=r" (s), "=r" (tmp)
: "I" (I32_bit)
: "cc");
return (s);
}
static __inline void
intr_restore(int s)
{
__asm __volatile("msr cpsr_all, %0 "
: /* no output */
: "r" (s)
: "cc");
}
struct cpu_functions {
/* CPU functions */
u_int (*cf_id) (void);
void (*cf_cpwait) (void);
/* MMU functions */
u_int (*cf_control) (u_int bic, u_int eor);
void (*cf_domains) (u_int domains);
void (*cf_setttb) (u_int ttb);
u_int (*cf_faultstatus) (void);
u_int (*cf_faultaddress) (void);
/* TLB functions */
void (*cf_tlb_flushID) (void);
void (*cf_tlb_flushID_SE) (u_int va);
void (*cf_tlb_flushI) (void);
void (*cf_tlb_flushI_SE) (u_int va);
void (*cf_tlb_flushD) (void);
void (*cf_tlb_flushD_SE) (u_int va);
/*
* Cache operations:
*
* We define the following primitives:
*
* icache_sync_all Synchronize I-cache
* icache_sync_range Synchronize I-cache range
*
* dcache_wbinv_all Write-back and Invalidate D-cache
* dcache_wbinv_range Write-back and Invalidate D-cache range
* dcache_inv_range Invalidate D-cache range
* dcache_wb_range Write-back D-cache range
*
* idcache_wbinv_all Write-back and Invalidate D-cache,
* Invalidate I-cache
* idcache_wbinv_range Write-back and Invalidate D-cache,
* Invalidate I-cache range
*
* Note that the ARM term for "write-back" is "clean". We use
* the term "write-back" since it's a more common way to describe
* the operation.
*
* There are some rules that must be followed:
*
* I-cache Synch (all or range):
* The goal is to synchronize the instruction stream,
* so you may beed to write-back dirty D-cache blocks
* first. If a range is requested, and you can't
* synchronize just a range, you have to hit the whole
* thing.
*
* D-cache Write-Back and Invalidate range:
* If you can't WB-Inv a range, you must WB-Inv the
* entire D-cache.
*
* D-cache Invalidate:
* If you can't Inv the D-cache, you must Write-Back
* and Invalidate. Code that uses this operation
* MUST NOT assume that the D-cache will not be written
* back to memory.
*
* D-cache Write-Back:
* If you can't Write-back without doing an Inv,
* that's fine. Then treat this as a WB-Inv.
* Skipping the invalidate is merely an optimization.
*
* All operations:
* Valid virtual addresses must be passed to each
* cache operation.
*/
void (*cf_icache_sync_all) (void);
void (*cf_icache_sync_range) (vm_offset_t, vm_size_t);
void (*cf_dcache_wbinv_all) (void);
void (*cf_dcache_wbinv_range) (vm_offset_t, vm_size_t);
void (*cf_dcache_inv_range) (vm_offset_t, vm_size_t);
void (*cf_dcache_wb_range) (vm_offset_t, vm_size_t);
void (*cf_idcache_wbinv_all) (void);
void (*cf_idcache_wbinv_range) (vm_offset_t, vm_size_t);
/* Other functions */
void (*cf_flush_prefetchbuf) (void);
void (*cf_drain_writebuf) (void);
void (*cf_flush_brnchtgt_C) (void);
void (*cf_flush_brnchtgt_E) (u_int va);
void (*cf_sleep) (int mode);
/* Soft functions */
int (*cf_dataabt_fixup) (void *arg);
int (*cf_prefetchabt_fixup) (void *arg);
void (*cf_context_switch) (void);
void (*cf_setup) (char *string);
};
extern struct cpu_functions cpufuncs;
extern u_int cputype;
#define cpu_id() cpufuncs.cf_id()
#define cpu_cpwait() cpufuncs.cf_cpwait()
#define cpu_control(c, e) cpufuncs.cf_control(c, e)
#define cpu_domains(d) cpufuncs.cf_domains(d)
#define cpu_setttb(t) cpufuncs.cf_setttb(t)
#define cpu_faultstatus() cpufuncs.cf_faultstatus()
#define cpu_faultaddress() cpufuncs.cf_faultaddress()
#define cpu_tlb_flushID() cpufuncs.cf_tlb_flushID()
#define cpu_tlb_flushID_SE(e) cpufuncs.cf_tlb_flushID_SE(e)
#define cpu_tlb_flushI() cpufuncs.cf_tlb_flushI()
#define cpu_tlb_flushI_SE(e) cpufuncs.cf_tlb_flushI_SE(e)
#define cpu_tlb_flushD() cpufuncs.cf_tlb_flushD()
#define cpu_tlb_flushD_SE(e) cpufuncs.cf_tlb_flushD_SE(e)
#define cpu_icache_sync_all() cpufuncs.cf_icache_sync_all()
#define cpu_icache_sync_range(a, s) cpufuncs.cf_icache_sync_range((a), (s))
#define cpu_dcache_wbinv_all() cpufuncs.cf_dcache_wbinv_all()
#define cpu_dcache_wbinv_range(a, s) cpufuncs.cf_dcache_wbinv_range((a), (s))
#define cpu_dcache_inv_range(a, s) cpufuncs.cf_dcache_inv_range((a), (s))
#define cpu_dcache_wb_range(a, s) cpufuncs.cf_dcache_wb_range((a), (s))
#define cpu_idcache_wbinv_all() cpufuncs.cf_idcache_wbinv_all()
#define cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s))
#define cpu_flush_prefetchbuf() cpufuncs.cf_flush_prefetchbuf()
#define cpu_drain_writebuf() cpufuncs.cf_drain_writebuf()
#define cpu_flush_brnchtgt_C() cpufuncs.cf_flush_brnchtgt_C()
#define cpu_flush_brnchtgt_E(e) cpufuncs.cf_flush_brnchtgt_E(e)
#define cpu_sleep(m) cpufuncs.cf_sleep(m)
#define cpu_dataabt_fixup(a) cpufuncs.cf_dataabt_fixup(a)
#define cpu_prefetchabt_fixup(a) cpufuncs.cf_prefetchabt_fixup(a)
#define ABORT_FIXUP_OK 0 /* fixup succeeded */
#define ABORT_FIXUP_FAILED 1 /* fixup failed */
#define ABORT_FIXUP_RETURN 2 /* abort handler should return */
#define cpu_setup(a) cpufuncs.cf_setup(a)
int set_cpufuncs (void);
#define ARCHITECTURE_NOT_PRESENT 1 /* known but not configured */
#define ARCHITECTURE_NOT_SUPPORTED 2 /* not known */
void cpufunc_nullop (void);
int cpufunc_null_fixup (void *);
int early_abort_fixup (void *);
int late_abort_fixup (void *);
u_int cpufunc_id (void);
u_int cpufunc_control (u_int clear, u_int bic);
void cpufunc_domains (u_int domains);
u_int cpufunc_faultstatus (void);
u_int cpufunc_faultaddress (void);
#ifdef CPU_ARM3
u_int arm3_control (u_int clear, u_int bic);
void arm3_cache_flush (void);
#endif /* CPU_ARM3 */
#if defined(CPU_ARM6) || defined(CPU_ARM7)
void arm67_setttb (u_int ttb);
void arm67_tlb_flush (void);
void arm67_tlb_purge (u_int va);
void arm67_cache_flush (void);
void arm67_context_switch (void);
#endif /* CPU_ARM6 || CPU_ARM7 */
#ifdef CPU_ARM6
void arm6_setup (char *string);
#endif /* CPU_ARM6 */
#ifdef CPU_ARM7
void arm7_setup (char *string);
#endif /* CPU_ARM7 */
#ifdef CPU_ARM7TDMI
int arm7_dataabt_fixup (void *arg);
void arm7tdmi_setup (char *string);
void arm7tdmi_setttb (u_int ttb);
void arm7tdmi_tlb_flushID (void);
void arm7tdmi_tlb_flushID_SE (u_int va);
void arm7tdmi_cache_flushID (void);
void arm7tdmi_context_switch (void);
#endif /* CPU_ARM7TDMI */
#ifdef CPU_ARM8
void arm8_setttb (u_int ttb);
void arm8_tlb_flushID (void);
void arm8_tlb_flushID_SE (u_int va);
void arm8_cache_flushID (void);
void arm8_cache_flushID_E (u_int entry);
void arm8_cache_cleanID (void);
void arm8_cache_cleanID_E (u_int entry);
void arm8_cache_purgeID (void);
void arm8_cache_purgeID_E (u_int entry);
void arm8_cache_syncI (void);
void arm8_cache_cleanID_rng (vm_offset_t start, vm_size_t end);
void arm8_cache_cleanD_rng (vm_offset_t start, vm_size_t end);
void arm8_cache_purgeID_rng (vm_offset_t start, vm_size_t end);
void arm8_cache_purgeD_rng (vm_offset_t start, vm_size_t end);
void arm8_cache_syncI_rng (vm_offset_t start, vm_size_t end);
void arm8_context_switch (void);
void arm8_setup (char *string);
u_int arm8_clock_config (u_int, u_int);
#endif
#ifdef CPU_SA110
void sa110_setup (char *string);
void sa110_context_switch (void);
#endif /* CPU_SA110 */
#if defined(CPU_SA1100) || defined(CPU_SA1110)
void sa11x0_drain_readbuf (void);
void sa11x0_context_switch (void);
void sa11x0_cpu_sleep (int mode);
void sa11x0_setup (char *string);
#endif
#if defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110)
void sa1_setttb (u_int ttb);
void sa1_tlb_flushID_SE (u_int va);
void sa1_cache_flushID (void);
void sa1_cache_flushI (void);
void sa1_cache_flushD (void);
void sa1_cache_flushD_SE (u_int entry);
void sa1_cache_cleanID (void);
void sa1_cache_cleanD (void);
void sa1_cache_cleanD_E (u_int entry);
void sa1_cache_purgeID (void);
void sa1_cache_purgeID_E (u_int entry);
void sa1_cache_purgeD (void);
void sa1_cache_purgeD_E (u_int entry);
void sa1_cache_syncI (void);
void sa1_cache_cleanID_rng (vm_offset_t start, vm_size_t end);
void sa1_cache_cleanD_rng (vm_offset_t start, vm_size_t end);
void sa1_cache_purgeID_rng (vm_offset_t start, vm_size_t end);
void sa1_cache_purgeD_rng (vm_offset_t start, vm_size_t end);
void sa1_cache_syncI_rng (vm_offset_t start, vm_size_t end);
#endif
#ifdef CPU_ARM9
void arm9_setttb (u_int);
void arm9_tlb_flushID_SE (u_int va);
void arm9_cache_flushID (void);
void arm9_cache_flushID_SE (u_int);
void arm9_cache_flushI (void);
void arm9_cache_flushI_SE (u_int);
void arm9_cache_flushD (void);
void arm9_cache_flushD_SE (u_int);
void arm9_cache_cleanID (void);
void arm9_cache_syncI (void);
void arm9_cache_flushID_rng (vm_offset_t, vm_size_t);
void arm9_cache_flushD_rng (vm_offset_t, vm_size_t);
void arm9_cache_syncI_rng (vm_offset_t, vm_size_t);
void arm9_context_switch (void);
void arm9_setup (char *string);
#endif
#ifdef CPU_ARM10
void arm10_setttb (u_int);
void arm10_tlb_flushID_SE (u_int);
void arm10_tlb_flushI_SE (u_int);
void arm10_icache_sync_all (void);
void arm10_icache_sync_range (vm_offset_t, vm_size_t);
void arm10_dcache_wbinv_all (void);
void arm10_dcache_wbinv_range (vm_offset_t, vm_size_t);
void arm10_dcache_inv_range (vm_offset_t, vm_size_t);
void arm10_dcache_wb_range (vm_offset_t, vm_size_t);
void arm10_idcache_wbinv_all (void);
void arm10_idcache_wbinv_range (vm_offset_t, vm_size_t);
void arm10_context_switch (void);
void arm10_setup (char *string);
extern unsigned arm10_dcache_sets_max;
extern unsigned arm10_dcache_sets_inc;
extern unsigned arm10_dcache_index_max;
extern unsigned arm10_dcache_index_inc;
#endif
#if defined(CPU_ARM9) || defined(CPU_ARM10) || defined(CPU_SA110) || \
defined(CPU_SA1100) || defined(CPU_SA1110) || \
defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425)
void armv4_tlb_flushID (void);
void armv4_tlb_flushI (void);
void armv4_tlb_flushD (void);
void armv4_tlb_flushD_SE (u_int va);
void armv4_drain_writebuf (void);
#endif
#if defined(CPU_IXP12X0)
void ixp12x0_drain_readbuf (void);
void ixp12x0_context_switch (void);
void ixp12x0_setup (char *string);
#endif
#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425)
void xscale_cpwait (void);
void xscale_cpu_sleep (int mode);
u_int xscale_control (u_int clear, u_int bic);
void xscale_setttb (u_int ttb);
void xscale_tlb_flushID_SE (u_int va);
void xscale_cache_flushID (void);
void xscale_cache_flushI (void);
void xscale_cache_flushD (void);
void xscale_cache_flushD_SE (u_int entry);
void xscale_cache_cleanID (void);
void xscale_cache_cleanD (void);
void xscale_cache_cleanD_E (u_int entry);
void xscale_cache_clean_minidata (void);
void xscale_cache_purgeID (void);
void xscale_cache_purgeID_E (u_int entry);
void xscale_cache_purgeD (void);
void xscale_cache_purgeD_E (u_int entry);
void xscale_cache_syncI (void);
void xscale_cache_cleanID_rng (vm_offset_t start, vm_size_t end);
void xscale_cache_cleanD_rng (vm_offset_t start, vm_size_t end);
void xscale_cache_purgeID_rng (vm_offset_t start, vm_size_t end);
void xscale_cache_purgeD_rng (vm_offset_t start, vm_size_t end);
void xscale_cache_syncI_rng (vm_offset_t start, vm_size_t end);
void xscale_cache_flushD_rng (vm_offset_t start, vm_size_t end);
void xscale_context_switch (void);
void xscale_setup (char *string);
#endif /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 */
#define tlb_flush cpu_tlb_flushID
#define setttb cpu_setttb
#define drain_writebuf cpu_drain_writebuf
/*
* Macros for manipulating CPU interrupts
*/
static __inline u_int32_t __set_cpsr_c(u_int bic, u_int eor) __attribute__((__unused__));
static __inline u_int32_t
__set_cpsr_c(u_int bic, u_int eor)
{
u_int32_t tmp, ret;
__asm __volatile(
"mrs %0, cpsr\n" /* Get the CPSR */
"bic %1, %0, %2\n" /* Clear bits */
"eor %1, %1, %3\n" /* XOR bits */
"msr cpsr_c, %1\n" /* Set the control field of CPSR */
: "=&r" (ret), "=&r" (tmp)
: "r" (bic), "r" (eor));
return ret;
}
#define disable_interrupts(mask) \
(__set_cpsr_c((mask) & (I32_bit | F32_bit), \
(mask) & (I32_bit | F32_bit)))
#define enable_interrupts(mask) \
(__set_cpsr_c((mask) & (I32_bit | F32_bit), 0))
#define restore_interrupts(old_cpsr) \
(__set_cpsr_c((I32_bit | F32_bit), (old_cpsr) & (I32_bit | F32_bit)))
/* Functions to manipulate the CPSR. */
u_int SetCPSR(u_int bic, u_int eor);
u_int GetCPSR(void);
/*
* Functions to manipulate cpu r13
* (in arm/arm32/setstack.S)
*/
void set_stackptr __P((u_int mode, u_int address));
u_int get_stackptr __P((u_int mode));
/*
* Miscellany
*/
int get_pc_str_offset __P((void));
/*
* CPU functions from locore.S
*/
void cpu_reset __P((void)) __attribute__((__noreturn__));
/*
* Cache info variables.
*/
/* PRIMARY CACHE VARIABLES */
extern int arm_picache_size;
extern int arm_picache_line_size;
extern int arm_picache_ways;
extern int arm_pdcache_size; /* and unified */
extern int arm_pdcache_line_size;
extern int arm_pdcache_ways;
extern int arm_pcache_type;
extern int arm_pcache_unified;
extern int arm_dcache_align;
extern int arm_dcache_align_mask;
#endif /* _KERNEL */
#endif /* _MACHINE_CPUFUNC_H_ */
/* End of cpufunc.h */

View File

@ -0,0 +1,54 @@
/*-
* Copyright (c) 2002 Matthew Dillon. All Rights Reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file contains prototypes and high-level inlines related to
* machine-level critical function support:
*
* cpu_critical_enter() - inlined
* cpu_critical_exit() - inlined
* cpu_critical_fork_exit() - prototyped
* related support functions residing
* in <arch>/<arch>/critical.c - prototyped
*
* $FreeBSD$
*/
#ifndef MACHINE_CRITICAL_H
#define MACHINE_CRITICAL_H
void cpu_critical_fork_exit(void);
static __inline void
cpu_critical_enter(void)
{
curthread->td_md.md_savecrit = disable_interrupts(I32_bit | F32_bit);
}
static __inline void
cpu_critical_exit(void)
{
restore_interrupts(curthread->td_md.md_savecrit);
}
#endif

View File

@ -0,0 +1,75 @@
/*
* Mach Operating System
* Copyright (c) 1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*
* from: FreeBSD: src/sys/i386/include/db_machdep.h,v 1.16 1999/10/04
* $FreeBSD$
*/
#ifndef _MACHINE_DB_MACHDEP_H_
#define _MACHINE_DB_MACHDEP_H_
#include <machine/frame.h>
#include <machine/trap.h>
#include <machine/armreg.h>
#define BYTE_MSF (1)
#define T_BREAKPOINT (1)
typedef vm_offset_t db_addr_t;
typedef int db_expr_t;
typedef struct trapframe db_regs_t;
extern db_regs_t ddb_regs;
#define DDB_REGS (&ddb_regs)
#define PC_REGS(regs) ((db_addr_t)(regs)->tf_pc)
#define BKPT_INST (KERNEL_BREAKPOINT)
#define BKPT_SIZE (INSN_SIZE)
#define BKPT_SET(inst) (BKPT_INST)
#define BKPT_SKIP do { \
ddb_regs.tf_pc -= BKPT_SIZE; \
} while (0)
#define db_clear_single_step(regs)
#define db_set_single_step(regs)
#define IS_BREAKPOINT_TRAP(type, code) (type == T_BREAKPOINT)
#define IS_WATCHPOINT_TRAP(type, code) (0)
#define inst_trap_return(ins) (0)
#define inst_return(ins) (0)
#define inst_call(ins) (0)
#define inst_load(ins) (0)
#define inst_store(ins) (0)
#define DB_SMALL_VALUE_MAX (0x7fffffff)
#define DB_SMALL_VALUE_MIN (-0x40001)
#define DB_ELFSIZE 64
int db_validate_address(vm_offset_t);
#endif /* !_MACHINE_DB_MACHDEP_H_ */

View File

@ -0,0 +1,54 @@
/* $NetBSD: disassem.h,v 1.4 2001/03/04 04:15:58 matt Exp $ */
/*
* Copyright (c) 1997 Mark Brinicombe.
* Copyright (c) 1997 Causality Limited.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Define the interface structure required by the disassembler.
*
* $FreeBSD$
*/
#ifndef _MACHINE_DISASSEM_H_
#define _MACHINE_DISASSEM_H_
typedef struct {
u_int (*di_readword)(u_int);
void (*di_printaddr)(u_int);
void (*di_printf)(const char *, ...) __printflike(1, 2);
} disasm_interface_t;
/* Prototypes for callable functions */
vm_offset_t disasm(const disasm_interface_t *, vm_offset_t, int);
void disassemble(u_int);
#endif /* !_MACHINE_DISASSEM_H_ */

71
sys/arm/include/fiq.h Normal file
View File

@ -0,0 +1,71 @@
/* $NetBSD: fiq.h,v 1.1 2001/12/20 01:20:23 thorpej Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*
*/
#ifndef _MACHINE_FIQ_H_
#define _MACHINE_FIQ_H_
#include <sys/queue.h>
struct fiqregs {
u_int fr_r8; /* FIQ mode r8 */
u_int fr_r9; /* FIQ mode r9 */
u_int fr_r10; /* FIQ mode r10 */
u_int fr_r11; /* FIQ mode r11 */
u_int fr_r12; /* FIQ mode r12 */
u_int fr_r13; /* FIQ mode r13 */
};
struct fiqhandler {
TAILQ_ENTRY(fiqhandler) fh_list;/* link in the FIQ handler stack */
void *fh_func; /* FIQ handler routine */
size_t fh_size; /* size of FIQ handler */
int fh_flags; /* flags; see below */
struct fiqregs *fh_regs; /* pointer to regs structure */
};
#define FH_CANPUSH 0x01 /* can push this handler out of the way */
int fiq_claim(struct fiqhandler *);
void fiq_release(struct fiqhandler *);
void fiq_getregs(struct fiqregs *);
void fiq_setregs(struct fiqregs *);
#endif /* _MACHINE_FIQ_H_ */

75
sys/arm/include/float.h Normal file
View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 1989 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)float.h 7.1 (Berkeley) 5/8/90
* $FreeBSD$
*/
#ifndef _MACHINE_FLOAT_H_
#define _MACHINE_FLOAT_H_ 1
#define FLT_RADIX 2 /* b */
#define FLT_ROUNDS 1 /* FP addition rounds to nearest */
#define FLT_EVAL_METHOD (-1) /* i387 semantics are...interesting */
#define DECIMAL_DIG 21 /* max precision in decimal digits */
#define FLT_MANT_DIG 24 /* p */
#define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */
#define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */
#define FLT_MIN_EXP (-125) /* emin */
#define FLT_MIN 1.17549435E-38F /* b**(emin-1) */
#define FLT_MIN_10_EXP (-37) /* ceil(log10(b**(emin-1))) */
#define FLT_MAX_EXP 128 /* emax */
#define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */
#define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */
#define DBL_MANT_DIG 53
#define DBL_EPSILON 2.2204460492503131E-16
#define DBL_DIG 15
#define DBL_MIN_EXP (-1021)
#define DBL_MIN 2.2250738585072014E-308
#define DBL_MIN_10_EXP (-307)
#define DBL_MAX_EXP 1024
#define DBL_MAX 1.7976931348623157E+308
#define DBL_MAX_10_EXP 308
#define LDBL_MANT_DIG 64
#define LDBL_EPSILON 1.0842021724855044340E-19L
#define LDBL_DIG 18
#define LDBL_MIN_EXP (-16381)
#define LDBL_MIN 3.3621031431120935063E-4932L
#define LDBL_MIN_10_EXP (-4931)
#define LDBL_MAX_EXP 16384
#define LDBL_MAX 1.1897314953572317650E+4932L
#define LDBL_MAX_10_EXP 4932
#endif /* _MACHINE_FLOAT_H_ */

View File

@ -0,0 +1,42 @@
/*-
* Copyright (c) 1993 Andrew Moore, Talke Studio
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#) floatingpoint.h 1.0 (Berkeley) 9/23/93
* $FreeBSD$
*/
#ifndef _FLOATINGPOINT_H_
#define _FLOATINGPOINT_H_
#include <machine/ieeefp.h>
#endif /* !_FLOATINGPOINT_H_ */

88
sys/arm/include/fp.h Normal file
View File

@ -0,0 +1,88 @@
/* $NetBSD: fp.h,v 1.1 2001/01/10 19:02:06 bjh21 Exp $ */
/*
* Copyright (c) 1995 Mark Brinicombe.
* Copyright (c) 1995 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* fp.h
*
* FP info
*
* Created : 10/10/95
*
* $FreeBSD$
*/
#ifndef _MACHINE_FP_H
#define _MACHINE_FP_H
/*
* An extended precision floating point number
*/
typedef struct fp_extended_precision {
u_int32_t fp_exponent;
u_int32_t fp_mantissa_hi;
u_int32_t fp_mantissa_lo;
} fp_extended_precision_t;
typedef struct fp_extended_precision fp_reg_t;
/*
* Information about the FPE-SP state that is stored in the pcb
*
* This needs to move and be hidden from userland.
*/
struct fpe_sp_state {
unsigned int fp_flags;
unsigned int fp_sr;
unsigned int fp_cr;
fp_reg_t fp_registers[16];
};
/*
* Type for a saved FP context, if we want to translate the context to a
* user-readable form
*/
typedef struct {
u_int32_t fpsr;
fp_extended_precision_t regs[8];
} fp_state_t;
#endif /* _MACHINE_FP_H_ */
/* End of fp.h */

190
sys/arm/include/frame.h Normal file
View File

@ -0,0 +1,190 @@
/* $NetBSD: frame.h,v 1.5 2002/10/19 00:10:54 bjh21 Exp $ */
/*
* Copyright (c) 1994-1997 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* frame.h
*
* Stack frames structures
*
* Created : 30/09/94
*
* $FreeBSD$
*
*/
#ifndef _MACHINE_FRAME_H_
#define _MACHINE_FRAME_H_
#ifndef _LOCORE
#include <sys/signal.h>
#include <sys/ucontext.h>
/*
* Trap frame. Pushed onto the kernel stack on a trap (synchronous exception).
*/
typedef struct trapframe {
register_t tf_spsr; /* Zero on arm26 */
register_t tf_r0;
register_t tf_r1;
register_t tf_r2;
register_t tf_r3;
register_t tf_r4;
register_t tf_r5;
register_t tf_r6;
register_t tf_r7;
register_t tf_r8;
register_t tf_r9;
register_t tf_r10;
register_t tf_r11;
register_t tf_r12;
register_t tf_usr_sp;
register_t tf_usr_lr;
register_t tf_svc_sp; /* Not used on arm26 */
register_t tf_svc_lr; /* Not used on arm26 */
register_t tf_pc;
} trapframe_t;
/* Register numbers */
#define tf_r13 tf_usr_sp
#define tf_r14 tf_usr_lr
#define tf_r15 tf_pc
/*
* * Scheduler activations upcall frame. Pushed onto user stack before
* * calling an SA upcall.
* */
struct saframe {
#if 0 /* in registers on entry to upcall */
int sa_type;
struct sa_t ** sa_sas;
int sa_events;
int sa_interrupted;
#endif
void * sa_arg;
};
/*
* * Signal frame. Pushed onto user stack before calling sigcode.
* */
/* the pointers are use in the trampoline code to locate the ucontext */
struct sigframe {
siginfo_t sf_si; /* actual saved siginfo */
ucontext_t sf_uc; /* actual saved ucontext */
};
/*
* System stack frames.
*/
typedef struct irqframe {
unsigned int if_spsr;
unsigned int if_r0;
unsigned int if_r1;
unsigned int if_r2;
unsigned int if_r3;
unsigned int if_r4;
unsigned int if_r5;
unsigned int if_r6;
unsigned int if_r7;
unsigned int if_r8;
unsigned int if_r9;
unsigned int if_r10;
unsigned int if_r11;
unsigned int if_r12;
unsigned int if_usr_sp;
unsigned int if_usr_lr;
unsigned int if_svc_sp;
unsigned int if_svc_lr;
unsigned int if_pc;
} irqframe_t;
typedef struct clockframe {
unsigned int if_spsr;
unsigned int if_r0;
unsigned int if_r1;
unsigned int if_r2;
unsigned int if_r3;
unsigned int if_r4;
unsigned int if_r5;
unsigned int if_r6;
unsigned int if_r7;
unsigned int if_r8;
unsigned int if_r9;
unsigned int if_r10;
unsigned int if_r11;
unsigned int if_r12;
unsigned int if_usr_sp;
unsigned int if_usr_lr;
unsigned int if_svc_sp;
unsigned int if_svc_lr;
unsigned int if_pc;
} clockframe_t;
int kdb_trap(int, struct trapframe *);
/*
* Switch frame
*/
struct switchframe {
u_int sf_r4;
u_int sf_r5;
u_int sf_r6;
u_int sf_r7;
u_int sf_pc;
};
/*
* Stack frame. Used during stack traces (db_trace.c)
*/
struct frame {
u_int fr_fp;
u_int fr_sp;
u_int fr_lr;
u_int fr_pc;
};
#endif /* !_LOCORE */
#endif /* _MACHINE_FRAME_H_ */
/* End of frame.h */

154
sys/arm/include/ieee.h Normal file
View File

@ -0,0 +1,154 @@
/* $NetBSD: ieee754.h,v 1.4 2003/10/27 02:30:26 simonb Exp $ */
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ieee.h 8.1 (Berkeley) 6/11/93
*
* $FreeBSD$
*
*/
/*
* NOTICE: This is not a standalone file. To use it, #include it in
* your port's ieee.h header.
*/
#include <machine/endian.h>
/*
* <sys/ieee754.h> defines the layout of IEEE 754 floating point types.
* Only single-precision and double-precision types are defined here;
* extended types, if available, are defined in the machine-dependent
* header.
*/
/*
* Define the number of bits in each fraction and exponent.
*
* k k+1
* Note that 1.0 x 2 == 0.1 x 2 and that denorms are represented
*
* (-exp_bias+1)
* as fractions that look like 0.fffff x 2 . This means that
*
* -126
* the number 0.10000 x 2 , for instance, is the same as the normalized
*
* -127 -128
* float 1.0 x 2 . Thus, to represent 2 , we need one leading zero
*
* -129
* in the fraction; to represent 2 , we need two, and so on. This
*
* (-exp_bias-fracbits+1)
* implies that the smallest denormalized number is 2
*
* for whichever format we are talking about: for single precision, for
*
* -126 -149
* instance, we get .00000000000000000000001 x 2 , or 1.0 x 2 , and
*
* -149 == -127 - 23 + 1.
*/
#define SNG_EXPBITS 8
#define SNG_FRACBITS 23
#define DBL_EXPBITS 11
#define DBL_FRACBITS 52
struct ieee_single {
#if _BYTE_ORDER == _BIG_ENDIAN
u_int sng_sign:1;
u_int sng_exp:8;
u_int sng_frac:23;
#else
u_int sng_frac:23;
u_int sng_exp:8;
u_int sng_sign:1;
#endif
};
struct ieee_double {
#if _BYTE_ORDER == _BIG_ENDIAN
u_int dbl_sign:1;
u_int dbl_exp:11;
u_int dbl_frach:20;
u_int dbl_fracl;
#else
u_int dbl_fracl;
u_int dbl_frach:20;
u_int dbl_exp:11;
u_int dbl_sign:1;
#endif
};
/*
* Floats whose exponent is in [1..INFNAN) (of whatever type) are
* `normal'. Floats whose exponent is INFNAN are either Inf or NaN.
* Floats whose exponent is zero are either zero (iff all fraction
* bits are zero) or subnormal values.
*
* A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
* high fraction; if the bit is set, it is a `quiet NaN'.
*/
#define SNG_EXP_INFNAN 255
#define DBL_EXP_INFNAN 2047
#if 0
#define SNG_QUIETNAN (1 << 22)
#define DBL_QUIETNAN (1 << 19)
#endif
/*
* Exponent biases.
*/
#define SNG_EXP_BIAS 127
#define DBL_EXP_BIAS 1023
/*
* Convenience data structures.
*/
union ieee_single_u {
float sngu_f;
struct ieee_single sngu_sng;
};
union ieee_double_u {
double dblu_d;
struct ieee_double dblu_dbl;
};

51
sys/arm/include/ieeefp.h Normal file
View File

@ -0,0 +1,51 @@
/* $NetBSD: ieeefp.h,v 1.1 2001/01/10 19:02:06 bjh21 Exp $ */
/* $FreeBSD$ */
/*
* Based on ieeefp.h written by J.T. Conklin, Apr 28, 1995
* Public domain.
*/
#ifndef _MACHINE_IEEEFP_H_
#define _MACHINE_IEEEFP_H_
/* FP exception codes */
#define FP_EXCEPT_INV 0
#define FP_EXCEPT_DZ 1
#define FP_EXCEPT_OFL 2
#define FP_EXCEPT_UFL 3
#define FP_EXCEPT_IMP 4
/* Exception type (used by fpsetmask() et al.) */
typedef int fp_except;
/* Bit defines for fp_except */
#define FP_X_INV (1 << FP_EXCEPT_INV) /* invalid operation exception */
#define FP_X_DZ (1 << FP_EXCEPT_DZ) /* divide-by-zero exception */
#define FP_X_OFL (1 << FP_EXCEPT_OFL) /* overflow exception */
#define FP_X_UFL (1 << FP_EXCEPT_UFL) /* underflow exception */
#define FP_X_IMP (1 << FP_EXCEPT_IMP) /* imprecise (loss of precision; "inexact") */
/* Rounding modes */
typedef enum {
FP_RN=0, /* round to nearest representable number */
FP_RP=1, /* round toward positive infinity */
FP_RM=2, /* round toward negative infinity */
FP_RZ=3 /* round to zero (truncate) */
} fp_rnd_t;
/*
* FP precision modes
*/
typedef enum {
FP_PS=0, /* 24 bit (single-precision) */
FP_PRS, /* reserved */
FP_PD, /* 53 bit (double-precision) */
FP_PE /* 64 bit (extended-precision) */
} fp_prec_t;
#define fp_except_t int
#endif /* _MACHINE_IEEEFP_H_ */

View File

@ -0,0 +1,51 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from tahoe: in_cksum.c 1.2 86/01/05
* from: @(#)in_cksum.c 1.3 (Berkeley) 1/19/91
* from: Id: in_cksum.c,v 1.8 1995/12/03 18:35:19 bde Exp
* $FreeBSD$
*/
#ifndef _MACHINE_IN_CKSUM_H_
#define _MACHINE_IN_CKSUM_H_ 1
#include <sys/cdefs.h>
#ifdef _KERNEL
u_short in_cksum(struct mbuf *m, int len);
u_int in_cksum_hdr(const struct ip *ip);
u_short in_addword(u_short sum, u_short b);
u_short in_pseudo(u_int sum, u_int b, u_int c);
u_short in_cksum_skip(struct mbuf *m, int len, int skip);
#endif /* _KERNEL */
#endif /* _MACHINE_IN_CKSUM_H_ */

83
sys/arm/include/intr.h Normal file
View File

@ -0,0 +1,83 @@
/* $NetBSD: intr.h,v 1.7 2003/06/16 20:01:00 thorpej Exp $ */
/*
* Copyright (c) 1997 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe
* for the NetBSD Project.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*
*/
#ifndef _MACHINE_INTR_H_
#define _MACHINE_INTR_H_
/* Define the various Interrupt Priority Levels */
/* Hardware Interrupt Priority Levels are not mutually exclusive. */
#ifdef CPU_SA1110
#define IPL_SOFTCLOCK 0
#define IPL_SOFTNET 1
#define IPL_BIO 2 /* block I/O */
#define IPL_NET 3 /* network */
#define IPL_SOFTSERIAL 4
#define IPL_TTY 5 /* terminal */
#define IPL_VM 6 /* memory allocation */
#define IPL_AUDIO 7 /* audio */
#define IPL_CLOCK 8 /* clock */
#define IPL_HIGH 9 /* */
#define IPL_SERIAL 10 /* serial */
#define IPL_NONE 11
#define NIPL 12
#endif
#define IST_UNUSABLE -1 /* interrupt cannot be used */
#define IST_NONE 0 /* none (dummy) */
#define IST_PULSE 1 /* pulsed */
#define IST_EDGE 2 /* edge-triggered */
#define IST_LEVEL 3 /* level-triggered */
/* Software interrupt priority levels */
#define SOFTIRQ_CLOCK 0
#define SOFTIRQ_NET 1
#define SOFTIRQ_SERIAL 2
#define SOFTIRQ_BIT(x) (1 << x)
#include <machine/psl.h>
void set_splmasks(void);
void arm_setup_irqhandler(const char *, void (*)(void*), void *, int, int,
void **);
#endif /* _MACHINE_INTR_H */

103
sys/arm/include/katelib.h Normal file
View File

@ -0,0 +1,103 @@
/* $NetBSD: katelib.h,v 1.3 2001/11/23 19:21:48 thorpej Exp $ */
/*
* Copyright (c) 1994-1996 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* katelib.h
*
* Prototypes for machine specific functions. Most of these
* could be inlined.
*
* This should not really be a separate header file. Eventually I will merge
* this into other header files once I have decided where the declarations
* should go.
*
* Created : 18/09/94
*
* Based on kate/katelib/prototypes.h
*
* $FreeBSD$
*/
/*
* USE OF THIS FILE IS DEPRECATED
*/
#ifndef _MACHINE_KATELIB_H_
#define _MACHINE_KATELIB_H_
#include <sys/types.h>
#include <machine/cpufunc.h>
#ifdef _KERNEL
/* Assembly modules */
/* In blockio.S */
#include <machine/blockio.h>
/* Macros for reading and writing words, shorts, bytes */
#define WriteWord(a, b) \
*((volatile unsigned int *)(a)) = (b)
#define ReadWord(a) \
(*((volatile unsigned int *)(a)))
#define WriteShort(a, b) \
*((volatile unsigned int *)(a)) = ((b) | ((b) << 16))
#define ReadShort(a) \
((*((volatile unsigned int *)(a))) & 0xffff)
#define WriteByte(a, b) \
*((volatile unsigned char *)(a)) = (b)
#define ReadByte(a) \
(*((volatile unsigned char *)(a)))
/* Define in/out macros */
#define inb(port) ReadByte((port))
#define outb(port, byte) WriteByte((port), (byte))
#define inw(port) ReadShort((port))
#define outw(port, word) WriteShort((port), (word))
#define inl(port) ReadWord((port))
#define outl(port, lword) WriteWord((port), (lword))
#endif
#endif /* !_MACHINE_KATELIB_H_ */
/* End of katelib.h */

13
sys/arm/include/machdep.h Normal file
View File

@ -0,0 +1,13 @@
/* $NetBSD: machdep.h,v 1.7 2002/02/21 02:52:21 thorpej Exp $ */
/* $FreeBSD$ */
#ifndef _MACHDEP_BOOT_MACHDEP_H_
#define _MACHDEP_BOOT_MACHDEP_H_
/* misc prototypes used by the many arm machdeps */
void halt (void);
void data_abort_handler (trapframe_t *);
void prefetch_abort_handler (trapframe_t *);
void undefinedinstruction_bounce (trapframe_t *);
#endif /* !_MACHINE_MACHDEP_H_ */

36
sys/arm/include/md_var.h Normal file
View File

@ -0,0 +1,36 @@
/*-
* Copyright (c) 1995 Bruce D. Evans.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: FreeBSD: src/sys/i386/include/md_var.h,v 1.40 2001/07/12
* $FreeBSD$
*/
#ifndef _MACHINE_MD_VAR_H_
#define _MACHINE_MD_VAR_H_
#endif /* !_MACHINE_MD_VAR_H_ */

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2003 Peter Wemm <peter@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_METADATA_H_
#define _MACHINE_METADATA_H_
#define MODINFOMD_SMAP 0x1001
#endif /* !_MACHINE_METADATA_H_ */

32
sys/arm/include/mutex.h Normal file
View File

@ -0,0 +1,32 @@
/*-
* Copyright (c) 2001 Jake Burkholder.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_MUTEX_H_
#define _MACHINE_MUTEX_H_
#endif /* !_MACHINE_MUTEX_H_ */

View File

@ -55,10 +55,10 @@
#endif
#ifndef _MACHINE
#define _MACHIN "arm32"
#define _MACHINE "arm"
#endif
#ifndef _MACHINE_ARCH
#define _MACHINE_ARCH "arm32"
#define _MACHINE_ARCH "arm"
#endif
#ifndef _NO_NAMESPACE_POLLUTION
@ -67,14 +67,12 @@
#define _MACHINE_PARAM_H_
#ifndef MACHINE
#define MACHINE "arm32"
#define MACHINE "arm"
#endif
#ifndef MACHINE_ARCH
#define MACHINE_ARCH "arm32"
#define MACHINE_ARCH "arm"
#endif
#define MID_MACHINE MID_ARM32
#include <machine/cpu.h>
#define MID_MACHINE MID_ARM6
#ifdef SMP
#define MAXCPU 2
@ -90,12 +88,34 @@
#define PAGE_MASK (PAGE_SIZE - 1)
#define NPTEPG (PAGE_SIZE/(sizeof (pt_entry_t)))
#define KERNBASE 0x100000 /* start of kernel virtual */
#define BTOPKERNBASE ((u_long)KERNBASE >> PGSHIFT)
#define PDR_SHIFT 20 /* log2(NBPDR) */
#define NBPDR (1 << PDR_SHIFT)
#define NPDEPG (1 << (32 - PDR_SHIFT))
#define UPAGES 2 /* pages of u-area */
#define USPACE (UPAGES * PAGE_SIZE) /* total size of u-area */
#ifndef KSTACK_PAGES
#define KSTACK_PAGES 4
#endif /* !KSTACK_PAGES */
#ifndef UAREA_PAGES
#define UAREA_PAGES 2
#endif /* !UAREA_PAGES */
#ifndef USPACE
#define USPACE (UAREA_PAGES * PAGE_SIZE) /* total size of u-area */
#endif
#ifndef FPCONTEXTSIZE
#define FPCONTEXTSIZE (0x100)
#endif
#ifndef KSTACK_GUARD_PAGES
#define KSTACK_GUARD_PAGES 1
#endif /* !KSTACK_GUARD_PAGES */
#define USPACE_SVC_STACK_TOP (USPACE)
#define USPACE_SVC_STACK_BOTTOM (USPACE_SVC_STACK_TOP - 0x1000)
#define USPACE_UNDEF_STACK_TOP (USPACE_SVC_STACK_BOTTOM - 0x10)
#define USPACE_UNDEF_STACK_BOTTOM (FPCONTEXTSIZE + 10)
/*
* Mach derived conversion macros
*/

99
sys/arm/include/pcb.h Normal file
View File

@ -0,0 +1,99 @@
/* $NetBSD: pcb.h,v 1.10 2003/10/13 21:46:39 scw Exp $ */
/*
* Copyright (c) 2001 Matt Thomas <matt@3am-software.com>.
* Copyright (c) 1994 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the RiscBSD team.
* 4. The name "RiscBSD" nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY RISCBSD ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL RISCBSD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_PCB_H_
#define _MACHINE_PCB_H_
#include <machine/frame.h>
#include <machine/fp.h>
struct trapframe;
struct pcb_arm32 {
vm_offset_t pcb32_pagedir; /* PT hooks */
uint32_t *pcb32_pl1vec; /* PTR to vector_base L1 entry*/
uint32_t pcb32_l1vec; /* Value to stuff on ctx sw */
u_int pcb32_dacr; /* Domain Access Control Reg */
void *pcb32_cstate; /* &pmap->pm_cstate */
/*
* WARNING!
* cpuswitch.S relies on pcb32_r8 being quad-aligned in struct pcb
* (due to the use of "strd" when compiled for XSCALE)
*/
u_int pcb32_r8; /* used */
u_int pcb32_r9; /* used */
u_int pcb32_r10; /* used */
u_int pcb32_r11; /* used */
u_int pcb32_r12; /* used */
u_int pcb32_sp; /* used */
u_int pcb32_lr;
u_int pcb32_pc;
u_int pcb32_und_sp;
};
#define pcb_pagedir un_32.pcb32_pagedir
#define pcb_pl1vec un_32.pcb32_pl1vec
#define pcb_l1vec un_32.pcb32_l1vec
#define pcb_dacr un_32.pcb32_dacr
#define pcb_cstate un_32.pcb32_cstate
/*
* WARNING!
* See warning for struct pcb_arm32, above, before changing struct pcb!
*/
struct pcb {
u_int pcb_flags;
#define PCB_OWNFPU 0x00000001
#define PCB_NOALIGNFLT 0x00000002
caddr_t pcb_onfault; /* On fault handler */
struct pcb_arm32 un_32;
struct fpe_sp_state pcb_fpstate; /* Floating Point state */
};
/*
* No additional data for core dumps.
*/
struct md_coredump {
int md_empty;
};
#ifdef _KERNEL
extern struct pcb *curpcb;
void savectx(struct pcb *);
#endif /* _KERNEL */
#endif /* !_MACHINE_PCB_H_ */

60
sys/arm/include/pcpu.h Normal file
View File

@ -0,0 +1,60 @@
/*-
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27
* $FreeBSD$
*/
#ifndef _MACHINE_PCPU_H_
#define _MACHINE_PCPU_H_
#ifdef _KERNEL
#include <machine/asmacros.h>
#include <machine/frame.h>
#define ALT_STACK_SIZE 128
struct vmspace;
/*
* Inside the kernel, the globally reserved register g7 is used to
* point at the globaldata structure.
*/
#define PCPU_MD_FIELDS \
struct pcup *pc_prvspace;
struct pcb;
struct pcpu;
extern struct pcpu *pcpup;
#define PCPU_GET(member) (pcpup->pc_ ## member)
#define PCPU_PTR(member) (&pcpup->pc_ ## member)
#define PCPU_SET(member,value) (pcpup->pc_ ## member = (value))
#endif /* _KERNEL */
#endif /* !_MACHINE_PCPU_H_ */

586
sys/arm/include/pmap.h Normal file
View File

@ -0,0 +1,586 @@
/*
* Copyright (c) 1991 Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
* Science Department and William Jolitz of UUNET Technologies Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Derived from hp300 version by Mike Hibler, this version by William
* Jolitz uses a recursive map [a pde points to the page directory] to
* map the page tables using the pagetables themselves. This is done to
* reduce the impact on kernel virtual memory for lots of sparse address
* space, and to reduce the cost of memory to each process.
*
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
* from: FreeBSD: src/sys/i386/include/pmap.h,v 1.70 2000/11/30
*
* $FreeBSD$
*/
#ifndef _MACHINE_PMAP_H_
#define _MACHINE_PMAP_H_
#include <machine/pte.h>
/*
* Pte related macros
*/
#define PTE_NOCACHE 0
#define PTE_CACHE 1
#define VADDR(pdi, pti) ((vm_offset_t)(((pdi)<<PDR_SHIFT)+((pti)<<PAGE_SHIFT)))
#define PTDIPDE(ptd) ((ptd)/1024)
#define PTDIPTE(ptd) ((ptd)%256)
#ifndef NKPT
#define NKPT 120 /* actual number of kernel page tables */
#endif
#ifndef NKPDE
#define NKPDE 1019 /* Maximum number of kernel PDE */
#endif
#define NPDEPTD 16 /* Number of PDE in each PTD */
/*
* The *PTDI values control the layout of virtual memory
*/
#define KPTDI (NPDEPG-NKPDE) /* ptd entry for kernel space begin */
#define PTDPTDI (KPTDI-1) /* ptd entry that points to ptd! */
#define KPTPTDI (PTDPTDI-1) /* ptd entry for kernel PTEs */
#define UPTPTDI (KPTPTDI-3) /* ptd entry for uspace PTEs */
#define UMAXPTDI (UPTPTDI-1) /* ptd entry for user space end */
#define UMAXPTEOFF (NPTEPG) /* pte entry for user space end */
#ifndef LOCORE
#include <sys/queue.h>
#define PDESIZE sizeof(pd_entry_t) /* for assembly files */
#define PTESIZE sizeof(pt_entry_t) /* for assembly files */
#ifdef _KERNEL
#define ARM_PTE_TO_PFN(pte) ((pt_entry_t)(pte) >> PAGE_SHIFT)
#define ARM_PDE_TO_PFN(pde) ((pd_entry_t)(pde) >> 10)
#define ARM_PHYS_TO_KSPACE(x) ((vm_offset_t) (x) | (UPTPTDI << PDR_SHIFT))
#define ARM_KSPACE_TO_PHYS(x) ((vm_offset_t) (x) & ~(UPTPTDI << PDR_SHIFT))
extern pt_entry_t PTmap[], APTmap;
extern pd_entry_t PTD[], APTD, PTDpde, APTDpde;
extern pd_entry_t IdlePTD; /* physical address of "Idle" state directory */
#if 0
static __inline vm_offset_t
pmap_akextract(vm_offset_t va)
{
vm_offset_t pa;
pa = *(vm_offset_t *)avtopte(va);
pa = (pa & PG_FRAME) | (va & PAGE_MASK);
return pa;
}
#endif
#define vtophys(va) pmap_kextract(((vm_offset_t) (va)))
#define avtophys(va) pmap_akextract(((vm_offset_t) (va)))
#endif
/*
* Pmap sutff
*/
/*
* This structure is used to hold a virtual<->physical address
* association and is used mostly by bootstrap code
*/
struct pv_addr {
SLIST_ENTRY(pv_addr) pv_list;
vm_offset_t pv_va;
vm_paddr_t pv_pa;
};
struct pv_entry;
struct md_page {
int pvh_attrs;
u_int uro_mappings;
u_int urw_mappings;
union {
u_short s_mappings[2]; /* Assume kernel count <= 65535 */
u_int i_mappings;
} k_u;
#define kro_mappings k_u.s_mappings[0]
#define krw_mappings k_u.s_mappings[1]
#define k_mappings k_u.i_mappings
int pv_list_count;
TAILQ_HEAD(,pv_entry) pv_list;
};
#define VM_MDPAGE_INIT(pg) \
do { \
TAILQ_INIT(&pg->pv_list); \
mtx_init(&(pg)->md_page.pvh_mtx, "MDPAGE Mutex", NULL, MTX_DEV);\
(pg)->mdpage.pvh_attrs = 0; \
(pg)->mdpage.uro_mappings = 0; \
(pg)->mdpage.urw_mappings = 0; \
(pg)->mdpage.k_mappings = 0; \
} while (/*CONSTCOND*/0)
struct l1_ttable;
struct l2_dtable;
/*
* Track cache/tlb occupancy using the following structure
*/
union pmap_cache_state {
struct {
union {
u_int8_t csu_cache_b[2];
u_int16_t csu_cache;
} cs_cache_u;
union {
u_int8_t csu_tlb_b[2];
u_int16_t csu_tlb;
} cs_tlb_u;
} cs_s;
u_int32_t cs_all;
};
#define cs_cache_id cs_s.cs_cache_u.csu_cache_b[0]
#define cs_cache_d cs_s.cs_cache_u.csu_cache_b[1]
#define cs_cache cs_s.cs_cache_u.csu_cache
#define cs_tlb_id cs_s.cs_tlb_u.csu_tlb_b[0]
#define cs_tlb_d cs_s.cs_tlb_u.csu_tlb_b[1]
#define cs_tlb cs_s.cs_tlb_u.csu_tlb
/*
* Assigned to cs_all to force cacheops to work for a particular pmap
*/
#define PMAP_CACHE_STATE_ALL 0xffffffffu
/*
* The number of L2 descriptor tables which can be tracked by an l2_dtable.
* A bucket size of 16 provides for 16MB of contiguous virtual address
* space per l2_dtable. Most processes will, therefore, require only two or
* three of these to map their whole working set.
*/
#define L2_BUCKET_LOG2 4
#define L2_BUCKET_SIZE (1 << L2_BUCKET_LOG2)
/*
* Given the above "L2-descriptors-per-l2_dtable" constant, the number
* of l2_dtable structures required to track all possible page descriptors
* mappable by an L1 translation table is given by the following constants:
*/
#define L2_LOG2 ((32 - L1_S_SHIFT) - L2_BUCKET_LOG2)
#define L2_SIZE (1 << L2_LOG2)
struct pmap {
u_int8_t pm_domain;
struct l1_ttable *pm_l1;
struct l2_dtable *pm_l2[L2_SIZE];
pd_entry_t *pm_pdir; /* KVA of page directory */
TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */
struct pv_addr pm_ptpt; /* pagetable of pagetables */
int pm_count; /* reference count */
int pm_active; /* active on cpus */
struct pmap_statistics pm_stats; /* pmap statictics */
struct vm_page *pm_ptphint; /* pmap ptp hint */
union pmap_cache_state pm_cstate;
LIST_ENTRY(pmap) pm_list; /* List of all pmaps */
};
typedef struct pmap *pmap_t;
#ifdef _KERNEL
extern pmap_t kernel_pmap;
#define pmap_kernel() kernel_pmap
#endif
/*
* For each vm_page_t, there is a list of all currently valid virtual
* mappings of that page. An entry is a pv_entry_t, the list is pv_table.
*/
typedef struct pv_entry {
pmap_t pv_pmap; /* pmap where mapping lies */
vm_offset_t pv_va; /* virtual address for mapping */
TAILQ_ENTRY(pv_entry) pv_list;
TAILQ_ENTRY(pv_entry) pv_plist;
vm_page_t pv_ptem; /* VM page for pte */
int pv_flags; /* flags (wired, etc...) */
} *pv_entry_t;
#define PV_ENTRY_NULL ((pv_entry_t) 0)
#define PV_CI 0x01 /* all entries must be cache inhibited */
#define PV_PTPAGE 0x02 /* entry maps a page table page */
/*
* Page hooks.
* For speed we store the both the virtual address and the page table
* entry address for each page hook.
*/
typedef struct {
vm_offset_t va;
pt_entry_t *pte;
} pagehook_t;
#ifdef _KERNEL
boolean_t pmap_get_pde_pte(pmap_t, vm_offset_t, pd_entry_t **, pt_entry_t **);
/*
* virtual address to page table entry and
* to physical address. Likewise for alternate address space.
* Note: these work recursively, thus vtopte of a pte will give
* the corresponding pde that in turn maps it.
*/
void pmap_set_pcb_pagedir(pmap_t, struct pcb *);
/* Virtual address to page table entry */
static __inline pt_entry_t *
vtopte(vm_offset_t va)
{
pd_entry_t *pdep;
pt_entry_t *ptep;
if (pmap_get_pde_pte(pmap_kernel(), va, &pdep, &ptep) == FALSE)
return (NULL);
return (ptep);
}
extern vm_offset_t avail_end;
extern vm_offset_t clean_eva;
extern vm_offset_t clean_sva;
extern vm_offset_t phys_avail[];
extern vm_offset_t virtual_avail;
extern vm_offset_t virtual_end;
void pmap_bootstrap(vm_offset_t, vm_offset_t, struct pv_addr *);
void pmap_kenter(vm_offset_t va, vm_paddr_t pa);
void pmap_kremove(vm_offset_t);
void *pmap_mapdev(vm_offset_t, vm_size_t);
void pmap_unmapdev(vm_offset_t, vm_size_t);
vm_page_t pmap_use_pt(pmap_t, vm_offset_t);
void pmap_debug(int);
void pmap_map_section(vm_offset_t, vm_offset_t, vm_offset_t, int, int);
void pmap_link_l2pt(vm_offset_t, vm_offset_t, struct pv_addr *);
vm_size_t pmap_map_chunk(vm_offset_t, vm_offset_t, vm_offset_t, vm_size_t, int, int);
void
pmap_map_entry(vm_offset_t l1pt, vm_offset_t va, vm_offset_t pa, int prot,
int cache);
int pmap_fault_fixup(pmap_t, vm_offset_t, vm_prot_t, int);
/*
* Definitions for MMU domains
*/
#define PMAP_DOMAINS 15 /* 15 'user' domains (0-14) */
#define PMAP_DOMAIN_KERNEL 15 /* The kernel uses domain #15 */
/*
* The new pmap ensures that page-tables are always mapping Write-Thru.
* Thus, on some platforms we can run fast and loose and avoid syncing PTEs
* on every change.
*
* Unfortunately, not all CPUs have a write-through cache mode. So we
* define PMAP_NEEDS_PTE_SYNC for C code to conditionally do PTE syncs,
* and if there is the chance for PTE syncs to be needed, we define
* PMAP_INCLUDE_PTE_SYNC so e.g. assembly code can include (and run)
* the code.
*/
extern int pmap_needs_pte_sync;
/*
* These macros define the various bit masks in the PTE.
*
* We use these macros since we use different bits on different processor
* models.
*/
#define L1_S_PROT_U (L1_S_AP(AP_U))
#define L1_S_PROT_W (L1_S_AP(AP_W))
#define L1_S_PROT_MASK (L1_S_PROT_U|L1_S_PROT_W)
#define L1_S_CACHE_MASK_generic (L1_S_B|L1_S_C)
#define L1_S_CACHE_MASK_xscale (L1_S_B|L1_S_C|L1_S_XSCALE_TEX(TEX_XSCALE_X))
#define L2_L_PROT_U (L2_AP(AP_U))
#define L2_L_PROT_W (L2_AP(AP_W))
#define L2_L_PROT_MASK (L2_L_PROT_U|L2_L_PROT_W)
#define L2_L_CACHE_MASK_generic (L2_B|L2_C)
#define L2_L_CACHE_MASK_xscale (L2_B|L2_C|L2_XSCALE_L_TEX(TEX_XSCALE_X))
#define L2_S_PROT_U_generic (L2_AP(AP_U))
#define L2_S_PROT_W_generic (L2_AP(AP_W))
#define L2_S_PROT_MASK_generic (L2_S_PROT_U|L2_S_PROT_W)
#define L2_S_PROT_U_xscale (L2_AP0(AP_U))
#define L2_S_PROT_W_xscale (L2_AP0(AP_W))
#define L2_S_PROT_MASK_xscale (L2_S_PROT_U|L2_S_PROT_W)
#define L2_S_CACHE_MASK_generic (L2_B|L2_C)
#define L2_S_CACHE_MASK_xscale (L2_B|L2_C|L2_XSCALE_T_TEX(TEX_XSCALE_X))
#define L1_S_PROTO_generic (L1_TYPE_S | L1_S_IMP)
#define L1_S_PROTO_xscale (L1_TYPE_S)
#define L1_C_PROTO_generic (L1_TYPE_C | L1_C_IMP2)
#define L1_C_PROTO_xscale (L1_TYPE_C)
#define L2_L_PROTO (L2_TYPE_L)
#define L2_S_PROTO_generic (L2_TYPE_S)
#define L2_S_PROTO_xscale (L2_TYPE_XSCALE_XS)
/*
* User-visible names for the ones that vary with MMU class.
*/
#if ARM_NMMUS > 1
/* More than one MMU class configured; use variables. */
#define L2_S_PROT_U pte_l2_s_prot_u
#define L2_S_PROT_W pte_l2_s_prot_w
#define L2_S_PROT_MASK pte_l2_s_prot_mask
#define L1_S_CACHE_MASK pte_l1_s_cache_mask
#define L2_L_CACHE_MASK pte_l2_l_cache_mask
#define L2_S_CACHE_MASK pte_l2_s_cache_mask
#define L1_S_PROTO pte_l1_s_proto
#define L1_C_PROTO pte_l1_c_proto
#define L2_S_PROTO pte_l2_s_proto
#elif (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0
#define L2_S_PROT_U L2_S_PROT_U_generic
#define L2_S_PROT_W L2_S_PROT_W_generic
#define L2_S_PROT_MASK L2_S_PROT_MASK_generic
#define L1_S_CACHE_MASK L1_S_CACHE_MASK_generic
#define L2_L_CACHE_MASK L2_L_CACHE_MASK_generic
#define L2_S_CACHE_MASK L2_S_CACHE_MASK_generic
#define L1_S_PROTO L1_S_PROTO_generic
#define L1_C_PROTO L1_C_PROTO_generic
#define L2_S_PROTO L2_S_PROTO_generic
#elif ARM_MMU_XSCALE == 1
#define L2_S_PROT_U L2_S_PROT_U_xscale
#define L2_S_PROT_W L2_S_PROT_W_xscale
#define L2_S_PROT_MASK L2_S_PROT_MASK_xscale
#define L1_S_CACHE_MASK L1_S_CACHE_MASK_xscale
#define L2_L_CACHE_MASK L2_L_CACHE_MASK_xscale
#define L2_S_CACHE_MASK L2_S_CACHE_MASK_xscale
#define L1_S_PROTO L1_S_PROTO_xscale
#define L1_C_PROTO L1_C_PROTO_xscale
#define L2_S_PROTO L2_S_PROTO_xscale
#endif /* ARM_NMMUS > 1 */
#if (ARM_MMU_SA1 == 1) && (ARM_NMMUS == 1)
#define PMAP_NEEDS_PTE_SYNC 1
#define PMAP_INCLUDE_PTE_SYNC
#elif (ARM_MMU_SA1 == 0)
#define PMAP_NEEDS_PTE_SYNC 0
#endif
/*
* These macros return various bits based on kernel/user and protection.
* Note that the compiler will usually fold these at compile time.
*/
#define L1_S_PROT(ku, pr) ((((ku) == PTE_USER) ? L1_S_PROT_U : 0) | \
(((pr) & VM_PROT_WRITE) ? L1_S_PROT_W : 0))
#define L2_L_PROT(ku, pr) ((((ku) == PTE_USER) ? L2_L_PROT_U : 0) | \
(((pr) & VM_PROT_WRITE) ? L2_L_PROT_W : 0))
#define L2_S_PROT(ku, pr) ((((ku) == PTE_USER) ? L2_S_PROT_U : 0) | \
(((pr) & VM_PROT_WRITE) ? L2_S_PROT_W : 0))
/*
* Macros to test if a mapping is mappable with an L1 Section mapping
* or an L2 Large Page mapping.
*/
#define L1_S_MAPPABLE_P(va, pa, size) \
((((va) | (pa)) & L1_S_OFFSET) == 0 && (size) >= L1_S_SIZE)
#define L2_L_MAPPABLE_P(va, pa, size) \
((((va) | (pa)) & L2_L_OFFSET) == 0 && (size) >= L2_L_SIZE)
/*
* Provide a fallback in case we were not able to determine it at
* compile-time.
*/
#ifndef PMAP_NEEDS_PTE_SYNC
#define PMAP_NEEDS_PTE_SYNC pmap_needs_pte_sync
#define PMAP_INCLUDE_PTE_SYNC
#endif
#define PTE_SYNC(pte) \
do { \
if (PMAP_NEEDS_PTE_SYNC) \
cpu_dcache_wb_range((vm_offset_t)(pte), sizeof(pt_entry_t));\
} while (/*CONSTCOND*/0)
#define PTE_SYNC_RANGE(pte, cnt) \
do { \
if (PMAP_NEEDS_PTE_SYNC) { \
cpu_dcache_wb_range((vm_offset_t)(pte), \
(cnt) << 2); /* * sizeof(pt_entry_t) */ \
} \
} while (/*CONSTCOND*/0)
extern pt_entry_t pte_l1_s_cache_mode;
extern pt_entry_t pte_l1_s_cache_mask;
extern pt_entry_t pte_l2_l_cache_mode;
extern pt_entry_t pte_l2_l_cache_mask;
extern pt_entry_t pte_l2_s_cache_mode;
extern pt_entry_t pte_l2_s_cache_mask;
extern pt_entry_t pte_l1_s_cache_mode_pt;
extern pt_entry_t pte_l2_l_cache_mode_pt;
extern pt_entry_t pte_l2_s_cache_mode_pt;
extern pt_entry_t pte_l2_s_prot_u;
extern pt_entry_t pte_l2_s_prot_w;
extern pt_entry_t pte_l2_s_prot_mask;
extern pt_entry_t pte_l1_s_proto;
extern pt_entry_t pte_l1_c_proto;
extern pt_entry_t pte_l2_s_proto;
extern void (*pmap_copy_page_func)(vm_paddr_t, vm_paddr_t);
extern void (*pmap_zero_page_func)(vm_paddr_t, int, int);
#if (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0
void pmap_copy_page_generic(vm_paddr_t, vm_paddr_t);
void pmap_zero_page_generic(vm_paddr_t, int, int);
void pmap_pte_init_generic(void);
#if defined(CPU_ARM8)
void pmap_pte_init_arm8(void);
#endif
#if defined(CPU_ARM9)
void pmap_pte_init_arm9(void);
#endif /* CPU_ARM9 */
#if defined(CPU_ARM10)
void pmap_pte_init_arm10(void);
#endif /* CPU_ARM10 */
#endif /* (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0 */
#if /* ARM_MMU_SA1 == */1
void pmap_pte_init_sa1(void);
#endif /* ARM_MMU_SA1 == 1 */
#if ARM_MMU_XSCALE == 1
void pmap_copy_page_xscale(vm_paddr_t, vm_paddr_t);
void pmap_zero_page_xscale(vm_paddr_t, int, int);
void pmap_pte_init_xscale(void);
void xscale_setup_minidata(vm_offset_t, vm_offset_t, vm_offset_t);
#define PMAP_UAREA(va) pmap_uarea(va)
void pmap_uarea(vm_offset_t);
#endif /* ARM_MMU_XSCALE == 1 */
#define PTE_KERNEL 0
#define PTE_USER 1
#define l1pte_valid(pde) ((pde) != 0)
#define l1pte_section_p(pde) (((pde) & L1_TYPE_MASK) == L1_TYPE_S)
#define l1pte_page_p(pde) (((pde) & L1_TYPE_MASK) == L1_TYPE_C)
#define l1pte_fpage_p(pde) (((pde) & L1_TYPE_MASK) == L1_TYPE_F)
#define l2pte_index(v) (((v) & L2_ADDR_BITS) >> L2_S_SHIFT)
#define l2pte_valid(pte) ((pte) != 0)
#define l2pte_pa(pte) ((pte) & L2_S_FRAME)
#define l2pte_minidata(pte) (((pte) & \
(L2_B | L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X)))\
== (L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X)))
/* L1 and L2 page table macros */
#define pmap_pde_v(pde) l1pte_valid(*(pde))
#define pmap_pde_section(pde) l1pte_section_p(*(pde))
#define pmap_pde_page(pde) l1pte_page_p(*(pde))
#define pmap_pde_fpage(pde) l1pte_fpage_p(*(pde))
#define pmap_pte_v(pte) l2pte_valid(*(pte))
#define pmap_pte_pa(pte) l2pte_pa(*(pte))
/* Size of the kernel part of the L1 page table */
#define KERNEL_PD_SIZE \
(L1_TABLE_SIZE - (KERNEL_BASE >> L1_S_SHIFT) * sizeof(pd_entry_t))
#define PTE_PAGETABLE 2
/*
* Flags that indicate attributes of pages or mappings of pages.
*
* The PVF_MOD and PVF_REF flags are stored in the mdpage for each
* page. PVF_WIRED, PVF_WRITE, and PVF_NC are kept in individual
* pv_entry's for each page. They live in the same "namespace" so
* that we can clear multiple attributes at a time.
*
* Note the "non-cacheable" flag generally means the page has
* multiple mappings in a given address space.
*/
#define PVF_MOD 0x01 /* page is modified */
#define PVF_REF 0x02 /* page is referenced */
#define PVF_WIRED 0x04 /* mapping is wired */
#define PVF_WRITE 0x08 /* mapping is writable */
#define PVF_EXEC 0x10 /* mapping is executable */
#define PVF_UNC 0x20 /* mapping is 'user' non-cacheable */
#define PVF_KNC 0x40 /* mapping is 'kernel' non-cacheable */
#define PVF_NC (PVF_UNC|PVF_KNC)
void vector_page_setprot(int);
/*
* Routine: pmap_kextract
* Function:
* Extract the physical page address associated
* kernel virtual address.
*/
vm_paddr_t pmap_kextract(vm_offset_t);
void pmap_update(pmap_t);
#endif /* _KERNEL */
#endif /* !LOCORE */
#endif /* !_MACHINE_PMAP_H_ */

57
sys/arm/include/proc.h Normal file
View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 1991 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)proc.h 7.1 (Berkeley) 5/15/91
* from: FreeBSD: src/sys/i386/include/proc.h,v 1.11 2001/06/29
* $FreeBSD$
*/
#ifndef _MACHINE_PROC_H_
#define _MACHINE_PROC_H_
#include <machine/utrap.h>
struct md_utrap {
utrap_entry_t *ut_precise[UT_MAX]; /* must be first */
int ut_refcnt;
};
struct mdthread {
register_t md_savecrit;
};
struct mdproc {
struct md_utrap *md_utrap;
void *md_sigtramp;
};
#endif /* !_MACHINE_PROC_H_ */

139
sys/arm/include/profile.h Normal file
View File

@ -0,0 +1,139 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)profile.h 8.1 (Berkeley) 6/11/93
* $FreeBSD$
*/
#ifndef _MACHINE_PROFILE_H_
#define _MACHINE_PROFILE_H_
#ifdef _KERNEL
/*
* Config generates something to tell the compiler to align functions on 16
* byte boundaries. A strict alignment is good for keeping the tables small.
*/
#define FUNCTION_ALIGNMENT 16
/*
* The kernel uses assembler stubs instead of unportable inlines.
* This is mainly to save a little time when profiling is not enabled,
* which is the usual case for the kernel.
*/
#define _MCOUNT_DECL void mcount
#define MCOUNT
#ifdef GUPROF
#define CALIB_SCALE 1000
#define KCOUNT(p,index) ((p)->kcount[(index) \
/ (HISTFRACTION * sizeof(HISTCOUNTER))])
#define MCOUNT_DECL(s)
#define MCOUNT_ENTER(s)
#define MCOUNT_EXIT(s)
#define PC_TO_I(p, pc) ((uintfptr_t)(pc) - (uintfptr_t)(p)->lowpc)
#else
#define MCOUNT_DECL(s) u_long s;
#ifdef SMP
extern int mcount_lock;
#define MCOUNT_ENTER(s) { s = read_eflags(); disable_intr(); \
while (!atomic_cmpset_acq_int(&mcount_lock, 0, 1)) \
/* nothing */ ; }
#define MCOUNT_EXIT(s) { atomic_store_rel_int(&mcount_lock, 0); \
write_eflags(s); }
#else
#define MCOUNT_ENTER(s) { s = read_eflags(); disable_intr(); }
#define MCOUNT_EXIT(s) (write_eflags(s))
#endif
#endif /* GUPROF */
#else /* !_KERNEL */
#define FUNCTION_ALIGNMENT 4
#define _MCOUNT_DECL static __inline void _mcount
#define MCOUNT
typedef unsigned int uintfptr_t;
#endif /* _KERNEL */
/*
* An unsigned integral type that can hold non-negative difference between
* function pointers.
*/
typedef u_int fptrdiff_t;
#ifdef _KERNEL
void mcount(uintfptr_t frompc, uintfptr_t selfpc);
void kmupetext(uintfptr_t nhighpc);
#ifdef GUPROF
struct gmonparam;
void nullfunc_loop_profiled(void);
void nullfunc_profiled(void);
void startguprof(struct gmonparam *p);
void stopguprof(struct gmonparam *p);
#else
#define startguprof(p)
#define stopguprof(p)
#endif /* GUPROF */
#else /* !_KERNEL */
#include <sys/cdefs.h>
__BEGIN_DECLS
#ifdef __GNUC__
void mcount(void) __asm(".mcount");
#endif
__END_DECLS
#endif /* _KERNEL */
#ifdef GUPROF
/* XXX doesn't quite work outside kernel yet. */
extern int cputime_bias;
__BEGIN_DECLS
int cputime(void);
void empty_loop(void);
void mexitcount(uintfptr_t selfpc);
void nullfunc(void);
void nullfunc_loop(void);
__END_DECLS
#endif
#endif /* !_MACHINE_PROFILE_H_ */

83
sys/arm/include/psl.h Normal file
View File

@ -0,0 +1,83 @@
/* $NetBSD: psl.h,v 1.6 2003/06/16 20:00:58 thorpej Exp $ */
/*
* Copyright (c) 1995 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe
* for the NetBSD Project.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* psl.h
*
* spl prototypes.
* Eventually this will become a set of defines.
*
* Created : 21/07/95
*
* $FreeBSD$
*/
#ifndef _MACHINE_PSL_H_
#define _MACHINE_PSL_H_
#include <machine/intr.h>
/*
* These are the different SPL states
*
* Each state has an interrupt mask associated with it which
* indicate which interrupts are allowed.
*/
#define _SPL_0 0
#define _SPL_SOFTCLOCK 1
#define _SPL_SOFTNET 2
#define _SPL_BIO 3
#define _SPL_NET 4
#define _SPL_SOFTSERIAL 5
#define _SPL_TTY 6
#define _SPL_VM 7
#define _SPL_AUDIO 8
#define _SPL_CLOCK 9
#define _SPL_STATCLOCK 10
#define _SPL_HIGH 11
#define _SPL_SERIAL 12
#define _SPL_LEVELS 13
#ifdef _KERNEL
#ifndef _LOCORE
extern int current_spl_level;
extern u_int spl_masks[_SPL_LEVELS + 1];
extern u_int spl_smasks[_SPL_LEVELS];
#endif /* _LOCORE */
#endif /* _KERNEL */
#endif /* _ARM_PSL_H_ */
/* End of psl.h */

335
sys/arm/include/pte.h Normal file
View File

@ -0,0 +1,335 @@
/* $NetBSD: pte.h,v 1.1 2001/11/23 17:39:04 thorpej Exp $ */
/*
* Copyright (c) 1994 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the RiscBSD team.
* 4. The name "RiscBSD" nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY RISCBSD ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL RISCBSD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_PTE_H_
#define _MACHINE_PTE_H_
#define PDSHIFT 20 /* LOG2(NBPDR) */
#define NBPD (1 << PDSHIFT) /* bytes/page dir */
#define NPTEPD (NBPD / PAGE_SIZE)
#ifndef LOCORE
typedef uint32_t pd_entry_t; /* page directory entry */
typedef uint32_t pt_entry_t; /* page table entry */
#endif
#define PD_MASK 0xfff00000 /* page directory address bits */
#define PT_MASK 0x000ff000 /* page table address bits */
#define PG_FRAME 0xfffff000
/* The PT_SIZE definition is misleading... A page table is only 0x400
* bytes long. But since VM mapping can only be done to 0x1000 a single
* 1KB blocks cannot be steered to a va by itself. Therefore the
* pages tables are allocated in blocks of 4. i.e. if a 1 KB block
* was allocated for a PT then the other 3KB would also get mapped
* whenever the 1KB was mapped.
*/
#define PT_RSIZE 0x0400 /* Real page table size */
#define PT_SIZE 0x1000
#define PD_SIZE 0x4000
/* Access permissions for L1 sections and L2 pages */
#define AP_KR 0x00
#define AP_KRW 0x01
#define AP_KRWUR 0x02
#define AP_KRWURW 0x03
#define AP_W 0x01
#define AP_U 0x02
/* Physical bits in a pte */
#define PT_B 0x04 /* Phys - Buffered (write) */
#define PT_C 0x08 /* Phys - Cacheable */
#define PT_U 0x10 /* Phys - Updateable */
#ifndef LOCORE
extern pt_entry_t pte_cache_mode;
#define PT_CACHEABLE (pte_cache_mode)
#endif
/* Page R/M attributes (in pmseg.attrs). */
#define PT_M 0x01 /* Virt - Modified */
#define PT_H 0x02 /* Virt - Handled (Used) */
/* Mapping wired/writeable/cacheable attributes (in pv_flags). */
#define PT_W 0x04 /* Virt - Wired */
#define PT_Wr 0x08 /* Virt / Phys Write */
#define PT_NC 0x10 /* Cacheing disabled (multi-mapped page) */
/* access permissions for L2 pages (all sub pages have the same perms) */
#define PT_AP(x) ((x << 10) | (x << 8) | (x << 6) | (x << 4))
/* shift for access permissions in a L1 section mapping */
#define AP_SECTION_SHIFT 10
/* Page table types and masks */
#define L1_PAGE 0x01 /* L1 page table mapping */
#define L1_SECTION 0x02 /* L1 section mapping */
#define L1_FPAGE 0x03 /* L1 fine page mapping */
#define L1_MASK 0x03 /* Mask for L1 entry type */
#define L2_LPAGE 0x01 /* L2 large page (64KB) */
#define L2_SPAGE 0x02 /* L2 small page (4KB) */
#define L2_MASK 0x03 /* Mask for L2 entry type */
#define L2_INVAL 0x00 /* L2 invalid type */
/* PTE construction macros */
#define L2_LPTE(p, a, f) ((p) | PT_AP(a) | L2_LPAGE | (f))
#define L2_SPTE(p, a, f) ((p) | PT_AP(a) | L2_SPAGE | (f))
#define L2_PTE(p, a) L2_SPTE((p), (a), PT_CACHEABLE)
#define L2_PTE_NC(p, a) L2_SPTE((p), (a), PT_B)
#define L2_PTE_NC_NB(p, a) L2_SPTE((p), (a), 0)
#define L1_SECPTE(p, a, f) ((p) | ((a) << AP_SECTION_SHIFT) | (f) \
| L1_SECTION | PT_U)
#define L1_PTE(p) ((p) | 0x00 | L1_PAGE | PT_U)
#define L1_SEC(p, c) L1_SECPTE((p), AP_KRW, (c))
#define L1_SEC_SIZE (1 << PDSHIFT)
#define L2_LPAGE_SIZE (NBPG * 16)
/* Domain types */
#define DOMAIN_FAULT 0x00
#define DOMAIN_CLIENT 0x01
#define DOMAIN_RESERVED 0x02
#define DOMAIN_MANAGER 0x03
/* L1 and L2 address masks */
#define L1_ADDR_MASK 0xfffffc00
#define L2_ADDR_MASK 0xfffff000
/*
* The ARM MMU architecture was introduced with ARM v3 (previous ARM
* architecture versions used an optional off-CPU memory controller
* to perform address translation).
*
* The ARM MMU consists of a TLB and translation table walking logic.
* There is typically one TLB per memory interface (or, put another
* way, one TLB per software-visible cache).
*
* The ARM MMU is capable of mapping memory in the following chunks:
*
* 1M Sections (L1 table)
*
* 64K Large Pages (L2 table)
*
* 4K Small Pages (L2 table)
*
* 1K Tiny Pages (L2 table)
*
* There are two types of L2 tables: Coarse Tables and Fine Tables.
* Coarse Tables can map Large and Small Pages. Fine Tables can
* map Tiny Pages.
*
* Coarse Tables can define 4 Subpages within Large and Small pages.
* Subpages define different permissions for each Subpage within
* a Page.
*
* Coarse Tables are 1K in length. Fine tables are 4K in length.
*
* The Translation Table Base register holds the pointer to the
* L1 Table. The L1 Table is a 16K contiguous chunk of memory
* aligned to a 16K boundary. Each entry in the L1 Table maps
* 1M of virtual address space, either via a Section mapping or
* via an L2 Table.
*
* In addition, the Fast Context Switching Extension (FCSE) is available
* on some ARM v4 and ARM v5 processors. FCSE is a way of eliminating
* TLB/cache flushes on context switch by use of a smaller address space
* and a "process ID" that modifies the virtual address before being
* presented to the translation logic.
*/
#define L1_S_SIZE 0x00100000 /* 1M */
#define L1_S_OFFSET (L1_S_SIZE - 1)
#define L1_S_FRAME (~L1_S_OFFSET)
#define L1_S_SHIFT 20
#define L2_L_SIZE 0x00010000 /* 64K */
#define L2_L_OFFSET (L2_L_SIZE - 1)
#define L2_L_FRAME (~L2_L_OFFSET)
#define L2_L_SHIFT 16
#define L2_S_SIZE 0x00001000 /* 4K */
#define L2_S_OFFSET (L2_S_SIZE - 1)
#define L2_S_FRAME (~L2_S_OFFSET)
#define L2_S_SHIFT 12
#define L2_T_SIZE 0x00000400 /* 1K */
#define L2_T_OFFSET (L2_T_SIZE - 1)
#define L2_T_FRAME (~L2_T_OFFSET)
#define L2_T_SHIFT 10
/*
* The NetBSD VM implementation only works on whole pages (4K),
* whereas the ARM MMU's Coarse tables are sized in terms of 1K
* (16K L1 table, 1K L2 table).
*
* So, we allocate L2 tables 4 at a time, thus yielding a 4K L2
* table.
*/
#define L1_ADDR_BITS 0xfff00000 /* L1 PTE address bits */
#define L2_ADDR_BITS 0x000ff000 /* L2 PTE address bits */
#define L1_TABLE_SIZE 0x4000 /* 16K */
#define L2_TABLE_SIZE 0x1000 /* 4K */
/*
* The new pmap deals with the 1KB coarse L2 tables by
* allocating them from a pool. Until every port has been converted,
* keep the old L2_TABLE_SIZE define lying around. Converted ports
* should use L2_TABLE_SIZE_REAL until then.
*/
#define L2_TABLE_SIZE_REAL 0x400 /* 1K */
/*
* ARM L1 Descriptors
*/
#define L1_TYPE_INV 0x00 /* Invalid (fault) */
#define L1_TYPE_C 0x01 /* Coarse L2 */
#define L1_TYPE_S 0x02 /* Section */
#define L1_TYPE_F 0x03 /* Fine L2 */
#define L1_TYPE_MASK 0x03 /* mask of type bits */
/* L1 Section Descriptor */
#define L1_S_B 0x00000004 /* bufferable Section */
#define L1_S_C 0x00000008 /* cacheable Section */
#define L1_S_IMP 0x00000010 /* implementation defined */
#define L1_S_DOM(x) ((x) << 5) /* domain */
#define L1_S_DOM_MASK L1_S_DOM(0xf)
#define L1_S_AP(x) ((x) << 10) /* access permissions */
#define L1_S_ADDR_MASK 0xfff00000 /* phys address of section */
#define L1_S_XSCALE_P 0x00000200 /* ECC enable for this section */
#define L1_S_XSCALE_TEX(x) ((x) << 12) /* Type Extension */
/* L1 Coarse Descriptor */
#define L1_C_IMP0 0x00000004 /* implementation defined */
#define L1_C_IMP1 0x00000008 /* implementation defined */
#define L1_C_IMP2 0x00000010 /* implementation defined */
#define L1_C_DOM(x) ((x) << 5) /* domain */
#define L1_C_DOM_MASK L1_C_DOM(0xf)
#define L1_C_ADDR_MASK 0xfffffc00 /* phys address of L2 Table */
#define L1_C_XSCALE_P 0x00000200 /* ECC enable for this section */
/* L1 Fine Descriptor */
#define L1_F_IMP0 0x00000004 /* implementation defined */
#define L1_F_IMP1 0x00000008 /* implementation defined */
#define L1_F_IMP2 0x00000010 /* implementation defined */
#define L1_F_DOM(x) ((x) << 5) /* domain */
#define L1_F_DOM_MASK L1_F_DOM(0xf)
#define L1_F_ADDR_MASK 0xfffff000 /* phys address of L2 Table */
#define L1_F_XSCALE_P 0x00000200 /* ECC enable for this section */
/*
* ARM L2 Descriptors
*/
#define L2_TYPE_INV 0x00 /* Invalid (fault) */
#define L2_TYPE_L 0x01 /* Large Page */
#define L2_TYPE_S 0x02 /* Small Page */
#define L2_TYPE_T 0x03 /* Tiny Page */
#define L2_TYPE_MASK 0x03 /* mask of type bits */
/*
* This L2 Descriptor type is available on XScale processors
* when using a Coarse L1 Descriptor. The Extended Small
* Descriptor has the same format as the XScale Tiny Descriptor,
* but describes a 4K page, rather than a 1K page.
*/
#define L2_TYPE_XSCALE_XS 0x03 /* XScale Extended Small Page */
#define L2_B 0x00000004 /* Bufferable page */
#define L2_C 0x00000008 /* Cacheable page */
#define L2_AP0(x) ((x) << 4) /* access permissions (sp 0) */
#define L2_AP1(x) ((x) << 6) /* access permissions (sp 1) */
#define L2_AP2(x) ((x) << 8) /* access permissions (sp 2) */
#define L2_AP3(x) ((x) << 10) /* access permissions (sp 3) */
#define L2_AP(x) (L2_AP0(x) | L2_AP1(x) | L2_AP2(x) | L2_AP3(x))
#define L2_XSCALE_L_TEX(x) ((x) << 12) /* Type Extension */
#define L2_XSCALE_T_TEX(x) ((x) << 6) /* Type Extension */
/*
* Access Permissions for L1 and L2 Descriptors.
*/
#define AP_W 0x01 /* writable */
#define AP_U 0x02 /* user */
/*
* Short-hand for common AP_* constants.
*
* Note: These values assume the S (System) bit is set and
* the R (ROM) bit is clear in CP15 register 1.
*/
#define AP_KR 0x00 /* kernel read */
#define AP_KRW 0x01 /* kernel read/write */
#define AP_KRWUR 0x02 /* kernel read/write usr read */
#define AP_KRWURW 0x03 /* kernel read/write usr read/write */
/*
* Domain Types for the Domain Access Control Register.
*/
#define DOMAIN_FAULT 0x00 /* no access */
#define DOMAIN_CLIENT 0x01 /* client */
#define DOMAIN_RESERVED 0x02 /* reserved */
#define DOMAIN_MANAGER 0x03 /* manager */
/*
* Type Extension bits for XScale processors.
*
* Behavior of C and B when X == 0:
*
* C B Cacheable Bufferable Write Policy Line Allocate Policy
* 0 0 N N - -
* 0 1 N Y - -
* 1 0 Y Y Write-through Read Allocate
* 1 1 Y Y Write-back Read Allocate
*
* Behavior of C and B when X == 1:
* C B Cacheable Bufferable Write Policy Line Allocate Policy
* 0 0 - - - - DO NOT USE
* 0 1 N Y - -
* 1 0 Mini-Data - - -
* 1 1 Y Y Write-back R/W Allocate
*/
#define TEX_XSCALE_X 0x01 /* X modifies C and B */
#endif /* !_MACHINE_PTE_H_ */
/* End of pte.h */

8
sys/arm/include/ptrace.h Normal file
View File

@ -0,0 +1,8 @@
/* $NetBSD: ptrace.h,v 1.2 2001/02/23 21:23:52 reinoud Exp $ */
/* $FreeBSD$ */
#ifndef _MACHINE_PTRACE_H_
#define _MACHINE_PTRACE_H_
#endif /* !_MACHINE_PTRACE_H */

32
sys/arm/include/reg.h Normal file
View File

@ -0,0 +1,32 @@
/* $NetBSD: reg.h,v 1.2 2001/02/23 21:23:52 reinoud Exp $ */
/* $FreeBSD$ */
#ifndef MACHINE_REG_H
#define MACHINE_REG_H
#include <machine/fp.h>
struct reg {
unsigned int r[13];
unsigned int r_sp;
unsigned int r_lr;
unsigned int r_pc;
unsigned int r_cpsr;
};
struct fpreg {
unsigned int fpr_fpsr;
fp_reg_t fpr[8];
};
struct dbreg {
unsigned int dr[8]; /* debug registers */
};
int fill_regs(struct thread *, struct reg *);
int set_regs(struct thread *, struct reg *);
int fill_fpregs(struct thread *, struct fpreg *);
int set_fpregs(struct thread *, struct fpreg *);
int fill_dbregs(struct thread *, struct dbreg *);
int set_dbregs(struct thread *, struct dbreg *);
#endif /* !MACHINE_REG_H */

53
sys/arm/include/reloc.h Normal file
View File

@ -0,0 +1,53 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)reloc.h 8.1 (Berkeley) 6/10/93
* $FreeBSD$
*/
#ifndef _MACHINE_RELOC_H_
#define _MACHINE_RELOC_H_
/* Relocation format. */
struct relocation_info {
int r_address; /* offset in text or data segment */
unsigned int r_symbolnum : 24, /* ordinal number of add symbol */
r_pcrel : 1, /* 1 if value should be pc-relative */
r_length : 2, /* log base 2 of value's width */
r_extern : 1, /* 1 if need to add symbol to value */
r_baserel : 1, /* linkage table relative */
r_jmptable : 1, /* relocate to jump table */
r_relative : 1, /* load address relative */
r_copy : 1; /* run time copy */
};
#endif

View File

@ -0,0 +1,45 @@
/*
* Copyright 1998 Massachusetts Institute of Technology
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
* granted, provided that both the above copyright notice and this
* permission notice appear in all copies, that both the above
* copyright notice and this permission notice appear in all
* supporting documentation, and that the name of M.I.T. not be used
* in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. M.I.T. makes
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
* ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
* SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_RESOURCE_H_
#define _MACHINE_RESOURCE_H_ 1
/*
* Definitions of resource types for Intel Architecture machines
* with support for legacy ISA devices and drivers.
*/
#define SYS_RES_IRQ 1 /* interrupt lines */
#define SYS_RES_DRQ 2 /* isa dma lines */
#define SYS_RES_MEMORY 3 /* i/o memory */
#define SYS_RES_IOPORT 4 /* i/o ports */
#endif /* !_MACHINE_RESOURCE_H_ */

46
sys/arm/include/runq.h Normal file
View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2001 Jake Burkholder <jake@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_RUNQ_H_
#define _MACHINE_RUNQ_H_
#define RQB_LEN (2) /* Number of priority status words. */
#define RQB_L2BPW (5) /* Log2(sizeof(rqb_word_t) * NBBY)). */
#define RQB_BPW (1<<RQB_L2BPW) /* Bits in an rqb_word_t. */
#define RQB_BIT(pri) (1 << ((pri) & (RQB_BPW - 1)))
#define RQB_WORD(pri) ((pri) >> RQB_L2BPW)
#define RQB_FFS(word) (ffs(word) - 1)
/*
* Type of run queue status word.
*/
typedef u_int32_t rqb_word_t;
#endif

93
sys/arm/include/setjmp.h Normal file
View File

@ -0,0 +1,93 @@
/* $NetBSD: setjmp.h,v 1.2 2001/08/25 14:45:59 bjh21 Exp $ */
/* $FreeBSD$ */
/*
* machine/setjmp.h: machine dependent setjmp-related information.
*/
#ifdef __ELF__
#define _JBLEN 64 /* size, in longs, of a jmp_buf */
#else
#define _JBLEN 29 /* size, in longs, of a jmp_buf */
#endif
/*
* NOTE: The internal structure of a jmp_buf is *PRIVATE*
* This information is provided as there is software
* that fiddles with this with obtain the stack pointer
* (yes really ! and its commercial !).
*
* Description of the setjmp buffer
*
* word 0 magic number (dependant on creator)
* 1 - 3 f4 fp register 4
* 4 - 6 f5 fp register 5
* 7 - 9 f6 fp register 6
* 10 - 12 f7 fp register 7
* 13 fpsr fp status register
* 14 r4 register 4
* 15 r5 register 5
* 16 r6 register 6
* 17 r7 register 7
* 18 r8 register 8
* 19 r9 register 9
* 20 r10 register 10 (sl)
* 21 r11 register 11 (fp)
* 22 r12 register 12 (ip)
* 23 r13 register 13 (sp)
* 24 r14 register 14 (lr)
* 25 signal mask (dependant on magic)
* 26 (con't)
* 27 (con't)
* 28 (con't)
*
* The magic number number identifies the jmp_buf and
* how the buffer was created as well as providing
* a sanity check
*
* A side note I should mention - Please do not tamper
* with the floating point fields. While they are
* always saved and restored at the moment this cannot
* be garenteed especially if the compiler happens
* to be generating soft-float code so no fp
* registers will be used.
*
* Whilst this can be seen an encouraging people to
* use the setjmp buffer in this way I think that it
* is for the best then if changes occur compiles will
* break rather than just having new builds falling over
* mysteriously.
*/
#define _JB_MAGIC__SETJMP 0x4278f500
#define _JB_MAGIC_SETJMP 0x4278f501
/* Valid for all jmp_buf's */
#define _JB_MAGIC 0
#define _JB_REG_F4 1
#define _JB_REG_F5 4
#define _JB_REG_F6 7
#define _JB_REG_F7 10
#define _JB_REG_FPSR 13
#define _JB_REG_R4 14
#define _JB_REG_R5 15
#define _JB_REG_R6 16
#define _JB_REG_R7 17
#define _JB_REG_R8 18
#define _JB_REG_R9 19
#define _JB_REG_R10 20
#define _JB_REG_R11 21
#define _JB_REG_R12 22
#define _JB_REG_R13 23
#define _JB_REG_R14 24
/* Only valid with the _JB_MAGIC_SETJMP magic */
#define _JB_SIGMASK 25
#if __BSD_VISIBLE || __POSIX_VISIBLE || __XSI_VISIBLE
typedef struct _sigjmp_buf { int _sjb[_JBLEN + 1]; } sigjmp_buf[1];
#endif
typedef struct _jmp_buf { int _jb[_JBLEN + 1]; } jmp_buf[1];

58
sys/arm/include/sf_buf.h Normal file
View File

@ -0,0 +1,58 @@
/*-
* Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_SF_BUF_H_
#define _MACHINE_SF_BUF_H_
#include <sys/queue.h>
struct vm_page;
struct sf_buf {
LIST_ENTRY(sf_buf) list_entry; /* list of buffers */
TAILQ_ENTRY(sf_buf) free_entry; /* list of buffers */
struct vm_page *m; /* currently mapped page */
vm_offset_t kva; /* va of mapping */
int ref_count; /* usage of this mapping */
};
static __inline vm_offset_t
sf_buf_kva(struct sf_buf *sf)
{
return (sf->kva);
}
static __inline struct vm_page *
sf_buf_page(struct sf_buf *sf)
{
return (sf->m);
}
#endif /* !_MACHINE_SF_BUF_H_ */

Some files were not shown because too many files have changed in this diff Show More