Merge svn+ssh://svn.freebsd.org/base/head@214309

This commit is contained in:
Marcel Moolenaar 2010-10-26 02:34:47 +00:00
commit 6f3544cd70
1347 changed files with 77026 additions and 28560 deletions

View file

@ -20,23 +20,23 @@ WARNS?= 0
CFLAGS+= -ffreestanding -Wformat
CFLAGS+= -I${.CURDIR}
.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64"
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
CFLAGS+= -mpreferred-stack-boundary=2
CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2
.endif
.if ${MACHINE_ARCH} == "i386"
.if ${MACHINE_CPUARCH} == "i386"
CFLAGS+= -mno-sse3
.endif
.if ${MACHINE} == "pc98"
CFLAGS+= -Os
.endif
.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64"
.if ${MACHINE_CPUARCH} == "powerpc"
CFLAGS+= -msoft-float -D_STANDALONE -DNETIF_DEBUG
.endif
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "powerpc64"
CFLAGS+= -m32 -I.
.endif
.if ${MACHINE_ARCH} == "arm"
.if ${MACHINE_CPUARCH} == "arm"
CFLAGS+= -msoft-float -D_STANDALONE
.endif
@ -54,19 +54,19 @@ SRCS+= ntoh.c
# string functions from libc
.PATH: ${.CURDIR}/../libc/string
.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "powerpc" || \
${MACHINE_ARCH} == "powerpc64" || ${MACHINE_ARCH} == "sparc64" || \
${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "arm"
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "powerpc" || \
${MACHINE_CPUARCH} == "sparc64" || ${MACHINE_CPUARCH} == "amd64" || \
${MACHINE_CPUARCH} == "arm"
SRCS+= bcmp.c bcopy.c bzero.c ffs.c index.c memccpy.c memchr.c memcmp.c \
memcpy.c memmove.c memset.c qdivrem.c rindex.c strcat.c strchr.c \
strcmp.c strcpy.c strcspn.c strlen.c strncat.c strncmp.c strncpy.c \
strpbrk.c strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c
.endif
.if ${MACHINE_ARCH} == "arm"
.if ${MACHINE_CPUARCH} == "arm"
.PATH: ${.CURDIR}/../libc/arm/gen
SRCS+= divsi3.S
.endif
.if ${MACHINE_ARCH} == "ia64"
.if ${MACHINE_CPUARCH} == "ia64"
.PATH: ${.CURDIR}/../libc/ia64/string
SRCS+= bcmp.c bcopy.S bzero.S ffs.S index.c memccpy.c memchr.c memcmp.c \
memcpy.S memmove.S memset.c rindex.c strcat.c strchr.c \
@ -78,7 +78,7 @@ SRCS+= bcmp.c bcopy.S bzero.S ffs.S index.c memccpy.c memchr.c memcmp.c \
SRCS+= __divdi3.S __divsi3.S __moddi3.S __modsi3.S
SRCS+= __udivdi3.S __udivsi3.S __umoddi3.S __umodsi3.S
.endif
.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64"
.if ${MACHINE_CPUARCH} == "powerpc"
.PATH: ${.CURDIR}/../libc/quad
SRCS+= ashldi3.c ashrdi3.c
.PATH: ${.CURDIR}/../libc/powerpc/gen
@ -90,12 +90,12 @@ SRCS+= syncicache.c
SRCS+= uuid_equal.c uuid_is_nil.c
# _setjmp/_longjmp
.if ${MACHINE_ARCH} == "amd64"
.if ${MACHINE_CPUARCH} == "amd64"
.PATH: ${.CURDIR}/i386
.elif ${MACHINE_ARCH} == "powerpc64"
.PATH: ${.CURDIR}/powerpc
.else
.PATH: ${.CURDIR}/${MACHINE_ARCH}
.PATH: ${.CURDIR}/${MACHINE_CPUARCH}
.endif
SRCS+= _setjmp.S
@ -157,7 +157,7 @@ SRCS+= splitfs.c
.include <bsd.lib.mk>
.if ${MACHINE_ARCH} == "amd64"
.if ${MACHINE_CPUARCH} == "amd64"
beforedepend ${OBJS}: machine
cleandepend: cleanmachine
cleanmachine:

View file

@ -270,7 +270,6 @@ The
.Li b
conversion is provided to decode error registers.
Its usage is:
.Pp
.Bd -ragged -offset indent
printf(
.Qq reg=%b\en ,
@ -285,7 +284,6 @@ Each <arg> is a sequence of characters, the first of
which gives the bit number to be inspected (origin 1) and the next characters
(up to a character less than 32) give the text to be displayed if the bit is set.
Thus
.Pp
.Bd -ragged -offset indent
printf(
.Qq reg=%b\en ,
@ -295,7 +293,6 @@ printf(
.Ed
.Pp
would give the output
.Pp
.Bd -ragged -offset indent
reg=3<BITTWO,BITONE>
.Ed
@ -303,7 +300,6 @@ reg=3<BITTWO,BITONE>
The
.Li D
conversion provides a hexdump facility, e.g.
.Pp
.Bd -ragged -offset indent
printf(
.Qq %6D ,

View file

@ -50,7 +50,7 @@
#define MACPY(s, d) bcopy((char *)s, (char *)d, 6)
#define MAXTMO 20 /* seconds */
#define MAXTMO 120 /* seconds */
#define MINTMO 2 /* seconds */
#define FNAME_SIZE 128

View file

@ -50,7 +50,10 @@ __FBSDID("$FreeBSD$");
#define NFS_DEBUGxx
#define NFSREAD_SIZE 1024
/* Define our own NFS attributes without NQNFS stuff. */
#ifdef OLD_NFSV2
struct nfsv2_fattrs {
n_long fa_type;
n_long fa_mode;
@ -68,7 +71,6 @@ struct nfsv2_fattrs {
struct nfsv2_time fa_ctime;
};
struct nfs_read_args {
u_char fh[NFS_FHSIZE];
n_long off;
@ -77,7 +79,6 @@ struct nfs_read_args {
};
/* Data part of nfs rpc reply (also the largest thing we receive) */
#define NFSREAD_SIZE 1024
struct nfs_read_repl {
n_long errno;
struct nfsv2_fattrs fa;
@ -116,6 +117,72 @@ struct nfs_iodesc {
u_char fh[NFS_FHSIZE];
struct nfsv2_fattrs fa; /* all in network order */
};
#else /* !OLD_NFSV2 */
/* NFSv3 definitions */
#define NFS_V3MAXFHSIZE 64
#define NFS_VER3 3
#define RPCMNT_VER3 3
#define NFSPROCV3_LOOKUP 3
#define NFSPROCV3_READLINK 5
#define NFSPROCV3_READ 6
#define NFSPROCV3_READDIR 16
typedef struct {
uint32_t val[2];
} n_quad;
struct nfsv3_time {
uint32_t nfs_sec;
uint32_t nfs_nsec;
};
struct nfsv3_fattrs {
uint32_t fa_type;
uint32_t fa_mode;
uint32_t fa_nlink;
uint32_t fa_uid;
uint32_t fa_gid;
n_quad fa_size;
n_quad fa_used;
n_quad fa_rdev;
n_quad fa_fsid;
n_quad fa_fileid;
struct nfsv3_time fa_atime;
struct nfsv3_time fa_mtime;
struct nfsv3_time fa_ctime;
};
/*
* For NFSv3, the file handle is variable in size, so most fixed sized
* structures for arguments won't work. For most cases, a structure
* that starts with any fixed size section is followed by an array
* that covers the maximum size required.
*/
struct nfsv3_readdir_repl {
uint32_t errno;
uint32_t ok;
struct nfsv3_fattrs fa;
uint32_t cookiev0;
uint32_t cookiev1;
};
struct nfsv3_readdir_entry {
uint32_t follows;
uint32_t fid0;
uint32_t fid1;
uint32_t len;
uint32_t nameplus[0];
};
struct nfs_iodesc {
struct iodesc *iodesc;
off_t off;
uint32_t fhsize;
u_char fh[NFS_V3MAXFHSIZE];
struct nfsv3_fattrs fa; /* all in network order */
};
#endif /* OLD_NFSV2 */
/*
* XXX interactions with tftp? See nfswrapper.c for a confusing
@ -142,6 +209,7 @@ struct fs_ops nfs_fsops = {
nfs_readdir
};
#ifdef OLD_NFSV2
/*
* Fetch the root file handle (call mount daemon)
* Return zero or error number.
@ -745,3 +813,675 @@ nfs_readdir(struct open_file *f, struct dirent *d)
cookie = ntohl(roff->cookie);
return 0;
}
#else /* !OLD_NFSV2 */
/*
* Fetch the root file handle (call mount daemon)
* Return zero or error number.
*/
int
nfs_getrootfh(struct iodesc *d, char *path, uint32_t *fhlenp, u_char *fhp)
{
int len;
struct args {
uint32_t len;
char path[FNAME_SIZE];
} *args;
struct repl {
uint32_t errno;
uint32_t fhsize;
u_char fh[NFS_V3MAXFHSIZE];
uint32_t authcnt;
uint32_t auth[7];
} *repl;
struct {
uint32_t h[RPC_HEADER_WORDS];
struct args d;
} sdata;
struct {
uint32_t h[RPC_HEADER_WORDS];
struct repl d;
} rdata;
size_t cc;
#ifdef NFS_DEBUG
if (debug)
printf("nfs_getrootfh: %s\n", path);
#endif
args = &sdata.d;
repl = &rdata.d;
bzero(args, sizeof(*args));
len = strlen(path);
if (len > sizeof(args->path))
len = sizeof(args->path);
args->len = htonl(len);
bcopy(path, args->path, len);
len = sizeof(uint32_t) + roundup(len, sizeof(uint32_t));
cc = rpc_call(d, RPCPROG_MNT, RPCMNT_VER3, RPCMNT_MOUNT,
args, len, repl, sizeof(*repl));
if (cc == -1)
/* errno was set by rpc_call */
return (errno);
if (cc < 2 * sizeof (uint32_t))
return (EBADRPC);
if (repl->errno != 0)
return (ntohl(repl->errno));
*fhlenp = ntohl(repl->fhsize);
bcopy(repl->fh, fhp, *fhlenp);
return (0);
}
/*
* Lookup a file. Store handle and attributes.
* Return zero or error number.
*/
int
nfs_lookupfh(struct nfs_iodesc *d, const char *name, struct nfs_iodesc *newfd)
{
int len, rlen, pos;
struct args {
uint32_t fhsize;
uint32_t fhplusname[1 +
(NFS_V3MAXFHSIZE + FNAME_SIZE) / sizeof(uint32_t)];
} *args;
struct repl {
uint32_t errno;
uint32_t fhsize;
uint32_t fhplusattr[(NFS_V3MAXFHSIZE +
2 * (sizeof(uint32_t) +
sizeof(struct nfsv3_fattrs))) / sizeof(uint32_t)];
} *repl;
struct {
uint32_t h[RPC_HEADER_WORDS];
struct args d;
} sdata;
struct {
uint32_t h[RPC_HEADER_WORDS];
struct repl d;
} rdata;
ssize_t cc;
#ifdef NFS_DEBUG
if (debug)
printf("lookupfh: called\n");
#endif
args = &sdata.d;
repl = &rdata.d;
bzero(args, sizeof(*args));
args->fhsize = htonl(d->fhsize);
bcopy(d->fh, args->fhplusname, d->fhsize);
len = strlen(name);
if (len > FNAME_SIZE)
len = FNAME_SIZE;
pos = roundup(d->fhsize, sizeof(uint32_t)) / sizeof(uint32_t);
args->fhplusname[pos++] = htonl(len);
bcopy(name, &args->fhplusname[pos], len);
len = sizeof(uint32_t) + pos * sizeof(uint32_t) +
roundup(len, sizeof(uint32_t));
rlen = sizeof(*repl);
cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_LOOKUP,
args, len, repl, rlen);
if (cc == -1)
return (errno); /* XXX - from rpc_call */
if (cc < 2 * sizeof(uint32_t))
return (EIO);
if (repl->errno != 0)
/* saerrno.h now matches NFS error numbers. */
return (ntohl(repl->errno));
newfd->fhsize = ntohl(repl->fhsize);
bcopy(repl->fhplusattr, &newfd->fh, newfd->fhsize);
pos = roundup(newfd->fhsize, sizeof(uint32_t)) / sizeof(uint32_t);
if (repl->fhplusattr[pos++] == 0)
return (EIO);
bcopy(&repl->fhplusattr[pos], &newfd->fa, sizeof(newfd->fa));
return (0);
}
#ifndef NFS_NOSYMLINK
/*
* Get the destination of a symbolic link.
*/
int
nfs_readlink(struct nfs_iodesc *d, char *buf)
{
struct args {
uint32_t fhsize;
u_char fh[NFS_V3MAXFHSIZE];
} *args;
struct repl {
uint32_t errno;
uint32_t ok;
struct nfsv3_fattrs fa;
uint32_t len;
u_char path[NFS_MAXPATHLEN];
} *repl;
struct {
uint32_t h[RPC_HEADER_WORDS];
struct args d;
} sdata;
struct {
uint32_t h[RPC_HEADER_WORDS];
struct repl d;
} rdata;
ssize_t cc;
#ifdef NFS_DEBUG
if (debug)
printf("readlink: called\n");
#endif
args = &sdata.d;
repl = &rdata.d;
bzero(args, sizeof(*args));
args->fhsize = htonl(d->fhsize);
bcopy(d->fh, args->fh, d->fhsize);
cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READLINK,
args, sizeof(uint32_t) + roundup(d->fhsize, sizeof(uint32_t)),
repl, sizeof(*repl));
if (cc == -1)
return (errno);
if (cc < 2 * sizeof(uint32_t))
return (EIO);
if (repl->errno != 0)
return (ntohl(repl->errno));
if (repl->ok == 0)
return (EIO);
repl->len = ntohl(repl->len);
if (repl->len > NFS_MAXPATHLEN)
return (ENAMETOOLONG);
bcopy(repl->path, buf, repl->len);
buf[repl->len] = 0;
return (0);
}
#endif
/*
* Read data from a file.
* Return transfer count or -1 (and set errno)
*/
ssize_t
nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len)
{
struct args {
uint32_t fhsize;
uint32_t fhoffcnt[NFS_V3MAXFHSIZE / sizeof(uint32_t) + 3];
} *args;
struct repl {
uint32_t errno;
uint32_t ok;
struct nfsv3_fattrs fa;
uint32_t count;
uint32_t eof;
uint32_t len;
u_char data[NFSREAD_SIZE];
} *repl;
struct {
uint32_t h[RPC_HEADER_WORDS];
struct args d;
} sdata;
struct {
uint32_t h[RPC_HEADER_WORDS];
struct repl d;
} rdata;
size_t cc;
long x;
int hlen, rlen, pos;
args = &sdata.d;
repl = &rdata.d;
bzero(args, sizeof(*args));
args->fhsize = htonl(d->fhsize);
bcopy(d->fh, args->fhoffcnt, d->fhsize);
pos = roundup(d->fhsize, sizeof(uint32_t)) / sizeof(uint32_t);
args->fhoffcnt[pos++] = 0;
args->fhoffcnt[pos++] = htonl((uint32_t)off);
if (len > NFSREAD_SIZE)
len = NFSREAD_SIZE;
args->fhoffcnt[pos] = htonl((uint32_t)len);
hlen = sizeof(*repl) - NFSREAD_SIZE;
cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READ,
args, 4 * sizeof(uint32_t) + roundup(d->fhsize, sizeof(uint32_t)),
repl, sizeof(*repl));
if (cc == -1)
/* errno was already set by rpc_call */
return (-1);
if (cc < hlen) {
errno = EBADRPC;
return (-1);
}
if (repl->errno != 0) {
errno = ntohl(repl->errno);
return (-1);
}
rlen = cc - hlen;
x = ntohl(repl->count);
if (rlen < x) {
printf("nfsread: short packet, %d < %ld\n", rlen, x);
errno = EBADRPC;
return (-1);
}
bcopy(repl->data, addr, x);
return (x);
}
/*
* Open a file.
* return zero or error number
*/
int
nfs_open(const char *upath, struct open_file *f)
{
struct iodesc *desc;
struct nfs_iodesc *currfd;
char buf[2 * NFS_V3MAXFHSIZE + 3];
u_char *fh;
char *cp;
int i;
#ifndef NFS_NOSYMLINK
struct nfs_iodesc *newfd;
struct nfsv3_fattrs *fa;
char *ncp;
int c;
char namebuf[NFS_MAXPATHLEN + 1];
char linkbuf[NFS_MAXPATHLEN + 1];
int nlinks = 0;
#endif
int error;
char *path;
#ifdef NFS_DEBUG
if (debug)
printf("nfs_open: %s (rootpath=%s)\n", upath, rootpath);
#endif
if (!rootpath[0]) {
printf("no rootpath, no nfs\n");
return (ENXIO);
}
/*
* This is silly - we should look at dv_type but that value is
* arch dependant and we can't use it here.
*/
#ifndef __i386__
if (strcmp(f->f_dev->dv_name, "net") != 0)
return (EINVAL);
#else
if (strcmp(f->f_dev->dv_name, "pxe") != 0)
return (EINVAL);
#endif
if (!(desc = socktodesc(*(int *)(f->f_devdata))))
return (EINVAL);
/* Bind to a reserved port. */
desc->myport = htons(--rpc_port);
desc->destip = rootip;
if ((error = nfs_getrootfh(desc, rootpath, &nfs_root_node.fhsize,
nfs_root_node.fh)))
return (error);
nfs_root_node.iodesc = desc;
fh = &nfs_root_node.fh[0];
buf[0] = 'X';
cp = &buf[1];
for (i = 0; i < nfs_root_node.fhsize; i++, cp += 2)
sprintf(cp, "%02x", fh[i]);
sprintf(cp, "X");
setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
setenv("boot.nfsroot.path", rootpath, 1);
setenv("boot.nfsroot.nfshandle", buf, 1);
sprintf(buf, "%d", nfs_root_node.fhsize);
setenv("boot.nfsroot.nfshandlelen", buf, 1);
#ifndef NFS_NOSYMLINK
/* Fake up attributes for the root dir. */
fa = &nfs_root_node.fa;
fa->fa_type = htonl(NFDIR);
fa->fa_mode = htonl(0755);
fa->fa_nlink = htonl(2);
currfd = &nfs_root_node;
newfd = 0;
cp = path = strdup(upath);
if (path == NULL) {
error = ENOMEM;
goto out;
}
while (*cp) {
/*
* Remove extra separators
*/
while (*cp == '/')
cp++;
if (*cp == '\0')
break;
/*
* Check that current node is a directory.
*/
if (currfd->fa.fa_type != htonl(NFDIR)) {
error = ENOTDIR;
goto out;
}
/* allocate file system specific data structure */
newfd = malloc(sizeof(*newfd));
if (newfd == NULL) {
error = ENOMEM;
goto out;
}
newfd->iodesc = currfd->iodesc;
newfd->off = 0;
/*
* Get next component of path name.
*/
{
int len = 0;
ncp = cp;
while ((c = *cp) != '\0' && c != '/') {
if (++len > NFS_MAXNAMLEN) {
error = ENOENT;
goto out;
}
cp++;
}
*cp = '\0';
}
/* lookup a file handle */
error = nfs_lookupfh(currfd, ncp, newfd);
*cp = c;
if (error)
goto out;
/*
* Check for symbolic link
*/
if (newfd->fa.fa_type == htonl(NFLNK)) {
int link_len, len;
error = nfs_readlink(newfd, linkbuf);
if (error)
goto out;
link_len = strlen(linkbuf);
len = strlen(cp);
if (link_len + len > MAXPATHLEN
|| ++nlinks > MAXSYMLINKS) {
error = ENOENT;
goto out;
}
bcopy(cp, &namebuf[link_len], len + 1);
bcopy(linkbuf, namebuf, link_len);
/*
* If absolute pathname, restart at root.
* If relative pathname, restart at parent directory.
*/
cp = namebuf;
if (*cp == '/') {
if (currfd != &nfs_root_node)
free(currfd);
currfd = &nfs_root_node;
}
free(newfd);
newfd = 0;
continue;
}
if (currfd != &nfs_root_node)
free(currfd);
currfd = newfd;
newfd = 0;
}
error = 0;
out:
free(newfd);
free(path);
#else
/* allocate file system specific data structure */
currfd = malloc(sizeof(*currfd));
if (currfd != NULL) {
currfd->iodesc = desc;
currfd->off = 0;
error = nfs_lookupfh(&nfs_root_node, upath, currfd);
} else
error = ENOMEM;
#endif
if (!error) {
f->f_fsdata = (void *)currfd;
return (0);
}
#ifdef NFS_DEBUG
if (debug)
printf("nfs_open: %s lookupfh failed: %s\n",
path, strerror(error));
#endif
#ifndef NFS_NOSYMLINK
if (currfd != &nfs_root_node)
#endif
free(currfd);
return (error);
}
int
nfs_close(struct open_file *f)
{
struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
#ifdef NFS_DEBUG
if (debug)
printf("nfs_close: fp=0x%lx\n", (u_long)fp);
#endif
if (fp != &nfs_root_node && fp)
free(fp);
f->f_fsdata = (void *)0;
return (0);
}
/*
* read a portion of a file
*/
int
nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
{
struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
ssize_t cc;
char *addr = buf;
#ifdef NFS_DEBUG
if (debug)
printf("nfs_read: size=%lu off=%d\n", (u_long)size,
(int)fp->off);
#endif
while ((int)size > 0) {
twiddle();
cc = nfs_readdata(fp, fp->off, (void *)addr, size);
/* XXX maybe should retry on certain errors */
if (cc == -1) {
#ifdef NFS_DEBUG
if (debug)
printf("nfs_read: read: %s", strerror(errno));
#endif
return (errno); /* XXX - from nfs_readdata */
}
if (cc == 0) {
#ifdef NFS_DEBUG
if (debug)
printf("nfs_read: hit EOF unexpectantly");
#endif
goto ret;
}
fp->off += cc;
addr += cc;
size -= cc;
}
ret:
if (resid)
*resid = size;
return (0);
}
/*
* Not implemented.
*/
int
nfs_write(struct open_file *f, void *buf, size_t size, size_t *resid)
{
return (EROFS);
}
off_t
nfs_seek(struct open_file *f, off_t offset, int where)
{
struct nfs_iodesc *d = (struct nfs_iodesc *)f->f_fsdata;
uint32_t size = ntohl(d->fa.fa_size.val[1]);
switch (where) {
case SEEK_SET:
d->off = offset;
break;
case SEEK_CUR:
d->off += offset;
break;
case SEEK_END:
d->off = size - offset;
break;
default:
errno = EINVAL;
return (-1);
}
return (d->off);
}
/* NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5, NFSOCK=6, NFFIFO=7 */
int nfs_stat_types[9] = {
0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFSOCK, S_IFIFO, 0 };
int
nfs_stat(struct open_file *f, struct stat *sb)
{
struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
uint32_t ftype, mode;
ftype = ntohl(fp->fa.fa_type);
mode = ntohl(fp->fa.fa_mode);
mode |= nfs_stat_types[ftype & 7];
sb->st_mode = mode;
sb->st_nlink = ntohl(fp->fa.fa_nlink);
sb->st_uid = ntohl(fp->fa.fa_uid);
sb->st_gid = ntohl(fp->fa.fa_gid);
sb->st_size = ntohl(fp->fa.fa_size.val[1]);
return (0);
}
static int
nfs_readdir(struct open_file *f, struct dirent *d)
{
struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
struct nfsv3_readdir_repl *repl;
struct nfsv3_readdir_entry *rent;
static char *buf;
static uint32_t cookie0 = 0;
static uint32_t cookie1 = 0;
size_t cc;
static uint32_t cookieverf0 = 0;
static uint32_t cookieverf1 = 0;
int pos;
struct args {
uint32_t fhsize;
uint32_t fhpluscookie[5 + NFS_V3MAXFHSIZE];
} *args;
struct {
uint32_t h[RPC_HEADER_WORDS];
struct args d;
} sdata;
static struct {
uint32_t h[RPC_HEADER_WORDS];
u_char d[NFS_READDIRSIZE];
} rdata;
if (cookie0 == 0 && cookie1 == 0) {
refill:
args = &sdata.d;
bzero(args, sizeof(*args));
args->fhsize = htonl(fp->fhsize);
bcopy(fp->fh, args->fhpluscookie, fp->fhsize);
pos = roundup(fp->fhsize, sizeof(uint32_t)) / sizeof(uint32_t);
args->fhpluscookie[pos++] = cookie0;
args->fhpluscookie[pos++] = cookie1;
args->fhpluscookie[pos++] = cookieverf0;
args->fhpluscookie[pos++] = cookieverf1;
args->fhpluscookie[pos] = htonl(NFS_READDIRSIZE);
cc = rpc_call(fp->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READDIR,
args, 6 * sizeof(uint32_t) +
roundup(fp->fhsize, sizeof(uint32_t)),
rdata.d, sizeof(rdata.d));
buf = rdata.d;
repl = (struct nfsv3_readdir_repl *)buf;
if (repl->errno != 0)
return (ntohl(repl->errno));
cookieverf0 = repl->cookiev0;
cookieverf1 = repl->cookiev1;
buf += sizeof (struct nfsv3_readdir_repl);
}
rent = (struct nfsv3_readdir_entry *)buf;
if (rent->follows == 0) {
/* fid0 is actually eof */
if (rent->fid0 != 0) {
cookie0 = 0;
cookie1 = 0;
cookieverf0 = 0;
cookieverf1 = 0;
return (ENOENT);
}
goto refill;
}
d->d_namlen = ntohl(rent->len);
bcopy(rent->nameplus, d->d_name, d->d_namlen);
d->d_name[d->d_namlen] = '\0';
pos = roundup(d->d_namlen, sizeof(uint32_t)) / sizeof(uint32_t);
cookie0 = rent->nameplus[pos++];
cookie1 = rent->nameplus[pos++];
buf = (u_char *)&rent->nameplus[pos];
return (0);
}
#endif /* OLD_NFSV2 */

View file

@ -338,19 +338,16 @@ ENTRY(savectx)
movl $MSR_FSBASE,%ecx
rdmsr
shlq $32,%rdx
leaq (%rax,%rdx),%rax
movq %rax,PCB_FSBASE(%rdi)
movl %eax,PCB_FSBASE(%rdi)
movl %edx,PCB_FSBASE+4(%rdi)
movl $MSR_GSBASE,%ecx
rdmsr
shlq $32,%rdx
leaq (%rax,%rdx),%rax
movq %rax,PCB_GSBASE(%rdi)
movl %eax,PCB_GSBASE(%rdi)
movl %edx,PCB_GSBASE+4(%rdi)
movl $MSR_KGSBASE,%ecx
rdmsr
shlq $32,%rdx
leaq (%rax,%rdx),%rax
movq %rax,PCB_KGSBASE(%rdi)
movl %eax,PCB_KGSBASE(%rdi)
movl %edx,PCB_KGSBASE+4(%rdi)
sgdt PCB_GDT(%rdi)
sidt PCB_IDT(%rdi)

View file

@ -108,6 +108,10 @@ IDTVEC(dbg)
TRAP_NOEN(T_TRCTRAP)
IDTVEC(bpt)
TRAP_NOEN(T_BPTFLT)
#ifdef KDTRACE_HOOKS
IDTVEC(dtrace_ret)
TRAP_NOEN(T_DTRACE_RET)
#endif
/* Regular traps; The cpu does not supply tf_err for these. */
#define TRAP(a) \

View file

@ -278,7 +278,7 @@ printcpuinfo(void)
"\017xTPR" /* Send Task Priority Messages*/
"\020PDCM" /* Perf/Debug Capability MSR */
"\021<b16>"
"\022<b17>"
"\022PCID" /* Process-context Identifiers */
"\023DCA" /* Direct Cache Access */
"\024SSE4.1"
"\025SSE4.2"

View file

@ -60,7 +60,7 @@ struct legacy_device {
static int legacy_probe(device_t);
static int legacy_attach(device_t);
static int legacy_print_child(device_t, device_t);
static device_t legacy_add_child(device_t bus, int order, const char *name,
static device_t legacy_add_child(device_t bus, u_int order, const char *name,
int unit);
static int legacy_read_ivar(device_t, device_t, int, uintptr_t *);
static int legacy_write_ivar(device_t, device_t, int, uintptr_t);
@ -149,7 +149,7 @@ legacy_print_child(device_t bus, device_t child)
}
static device_t
legacy_add_child(device_t bus, int order, const char *name, int unit)
legacy_add_child(device_t bus, u_int order, const char *name, int unit)
{
device_t child;
struct legacy_device *atdev;
@ -213,7 +213,7 @@ legacy_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
static void cpu_identify(driver_t *driver, device_t parent);
static int cpu_read_ivar(device_t dev, device_t child, int index,
uintptr_t *result);
static device_t cpu_add_child(device_t bus, int order, const char *name,
static device_t cpu_add_child(device_t bus, u_int order, const char *name,
int unit);
static struct resource_list *cpu_get_rlist(device_t dev, device_t child);
@ -277,7 +277,7 @@ cpu_identify(driver_t *driver, device_t parent)
}
static device_t
cpu_add_child(device_t bus, int order, const char *name, int unit)
cpu_add_child(device_t bus, u_int order, const char *name, int unit)
{
struct cpu_device *cd;
device_t child;

View file

@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include "opt_msgbuf.h"
#include "opt_perfmon.h"
#include "opt_sched.h"
#include "opt_kdtrace.h"
#include <sys/param.h>
#include <sys/proc.h>
@ -584,59 +585,89 @@ cpu_halt(void)
}
void (*cpu_idle_hook)(void) = NULL; /* ACPI idle hook. */
static int cpu_ident_amdc1e = 0; /* AMD C1E supported. */
static int idle_mwait = 1; /* Use MONITOR/MWAIT for short idle. */
TUNABLE_INT("machdep.idle_mwait", &idle_mwait);
SYSCTL_INT(_machdep, OID_AUTO, idle_mwait, CTLFLAG_RW, &idle_mwait,
0, "Use MONITOR/MWAIT for short idle");
static void
cpu_idle_hlt(int busy)
{
/*
* we must absolutely guarentee that hlt is the next instruction
* after sti or we introduce a timing window.
*/
disable_intr();
if (sched_runnable())
enable_intr();
else
__asm __volatile("sti; hlt");
}
#define STATE_RUNNING 0x0
#define STATE_MWAIT 0x1
#define STATE_SLEEPING 0x2
static void
cpu_idle_acpi(int busy)
{
int *state;
state = (int *)PCPU_PTR(monitorbuf);
*state = STATE_SLEEPING;
disable_intr();
if (sched_runnable())
if (sched_runnable())
enable_intr();
else if (cpu_idle_hook)
cpu_idle_hook();
else
__asm __volatile("sti; hlt");
*state = STATE_RUNNING;
}
static int cpu_ident_amdc1e = 0;
static int
cpu_probe_amdc1e(void)
static void
cpu_idle_hlt(int busy)
{
int *state;
state = (int *)PCPU_PTR(monitorbuf);
*state = STATE_SLEEPING;
/*
* We must absolutely guarentee that hlt is the next instruction
* after sti or we introduce a timing window.
*/
disable_intr();
if (sched_runnable())
enable_intr();
else
__asm __volatile("sti; hlt");
*state = STATE_RUNNING;
}
/*
* MWAIT cpu power states. Lower 4 bits are sub-states.
*/
#define MWAIT_C0 0xf0
#define MWAIT_C1 0x00
#define MWAIT_C2 0x10
#define MWAIT_C3 0x20
#define MWAIT_C4 0x30
static void
cpu_idle_mwait(int busy)
{
int *state;
state = (int *)PCPU_PTR(monitorbuf);
*state = STATE_MWAIT;
if (!sched_runnable()) {
cpu_monitor(state, 0, 0);
if (*state == STATE_MWAIT)
cpu_mwait(0, MWAIT_C1);
}
*state = STATE_RUNNING;
}
static void
cpu_idle_spin(int busy)
{
int *state;
int i;
/*
* Forget it, if we're not using local APIC timer.
*/
if (resource_disabled("apic", 0) ||
(resource_int_value("apic", 0, "clock", &i) == 0 && i == 0))
return (0);
/*
* Detect the presence of C1E capability mostly on latest
* dual-cores (or future) k8 family.
*/
if (cpu_vendor_id == CPU_VENDOR_AMD &&
(cpu_id & 0x00000f00) == 0x00000f00 &&
(cpu_id & 0x0fff0000) >= 0x00040000) {
cpu_ident_amdc1e = 1;
return (1);
state = (int *)PCPU_PTR(monitorbuf);
*state = STATE_RUNNING;
for (i = 0; i < 1000; i++) {
if (sched_runnable())
return;
cpu_spinwait();
}
return (0);
}
/*
@ -654,110 +685,83 @@ cpu_probe_amdc1e(void)
#define AMDK8_CMPHALT (AMDK8_SMIONCMPHALT | AMDK8_C1EONCMPHALT)
static void
cpu_idle_amdc1e(int busy)
cpu_probe_amdc1e(void)
{
disable_intr();
if (sched_runnable())
enable_intr();
else {
uint64_t msr;
msr = rdmsr(MSR_AMDK8_IPM);
if (msr & AMDK8_CMPHALT)
wrmsr(MSR_AMDK8_IPM, msr & ~AMDK8_CMPHALT);
if (cpu_idle_hook)
cpu_idle_hook();
else
__asm __volatile("sti; hlt");
/*
* Detect the presence of C1E capability mostly on latest
* dual-cores (or future) k8 family.
*/
if (cpu_vendor_id == CPU_VENDOR_AMD &&
(cpu_id & 0x00000f00) == 0x00000f00 &&
(cpu_id & 0x0fff0000) >= 0x00040000) {
cpu_ident_amdc1e = 1;
}
}
static void
cpu_idle_spin(int busy)
{
return;
}
void (*cpu_idle_fn)(int) = cpu_idle_acpi;
void
cpu_idle(int busy)
{
uint64_t msr;
CTR2(KTR_SPARE2, "cpu_idle(%d) at %d",
busy, curcpu);
#ifdef SMP
if (mp_grab_cpu_hlt())
return;
#endif
cpu_idle_fn(busy);
}
/*
* mwait cpu power states. Lower 4 bits are sub-states.
*/
#define MWAIT_C0 0xf0
#define MWAIT_C1 0x00
#define MWAIT_C2 0x10
#define MWAIT_C3 0x20
#define MWAIT_C4 0x30
#define MWAIT_DISABLED 0x0
#define MWAIT_WOKEN 0x1
#define MWAIT_WAITING 0x2
static void
cpu_idle_mwait(int busy)
{
int *mwait;
mwait = (int *)PCPU_PTR(monitorbuf);
*mwait = MWAIT_WAITING;
if (sched_runnable())
return;
cpu_monitor(mwait, 0, 0);
if (*mwait == MWAIT_WAITING)
cpu_mwait(0, MWAIT_C1);
}
static void
cpu_idle_mwait_hlt(int busy)
{
int *mwait;
mwait = (int *)PCPU_PTR(monitorbuf);
if (busy == 0) {
*mwait = MWAIT_DISABLED;
cpu_idle_hlt(busy);
return;
/* If we are busy - try to use fast methods. */
if (busy) {
if ((cpu_feature2 & CPUID2_MON) && idle_mwait) {
cpu_idle_mwait(busy);
goto out;
}
}
*mwait = MWAIT_WAITING;
if (sched_runnable())
return;
cpu_monitor(mwait, 0, 0);
if (*mwait == MWAIT_WAITING)
cpu_mwait(0, MWAIT_C1);
/* If we have time - switch timers into idle mode. */
if (!busy) {
critical_enter();
cpu_idleclock();
}
/* Apply AMD APIC timer C1E workaround. */
if (cpu_ident_amdc1e && cpu_disable_deep_sleep) {
msr = rdmsr(MSR_AMDK8_IPM);
if (msr & AMDK8_CMPHALT)
wrmsr(MSR_AMDK8_IPM, msr & ~AMDK8_CMPHALT);
}
/* Call main idle method. */
cpu_idle_fn(busy);
/* Switch timers mack into active mode. */
if (!busy) {
cpu_activeclock();
critical_exit();
}
out:
CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done",
busy, curcpu);
}
int
cpu_idle_wakeup(int cpu)
{
struct pcpu *pcpu;
int *mwait;
int *state;
if (cpu_idle_fn == cpu_idle_spin)
return (1);
if (cpu_idle_fn != cpu_idle_mwait && cpu_idle_fn != cpu_idle_mwait_hlt)
return (0);
pcpu = pcpu_find(cpu);
mwait = (int *)pcpu->pc_monitorbuf;
state = (int *)pcpu->pc_monitorbuf;
/*
* This doesn't need to be atomic since missing the race will
* simply result in unnecessary IPIs.
*/
if (cpu_idle_fn == cpu_idle_mwait_hlt && *mwait == MWAIT_DISABLED)
if (*state == STATE_SLEEPING)
return (0);
*mwait = MWAIT_WOKEN;
if (*state == STATE_MWAIT)
*state = STATE_RUNNING;
return (1);
}
@ -770,8 +774,6 @@ struct {
} idle_tbl[] = {
{ cpu_idle_spin, "spin" },
{ cpu_idle_mwait, "mwait" },
{ cpu_idle_mwait_hlt, "mwait_hlt" },
{ cpu_idle_amdc1e, "amdc1e" },
{ cpu_idle_hlt, "hlt" },
{ cpu_idle_acpi, "acpi" },
{ NULL, NULL }
@ -790,16 +792,20 @@ idle_sysctl_available(SYSCTL_HANDLER_ARGS)
if (strstr(idle_tbl[i].id_name, "mwait") &&
(cpu_feature2 & CPUID2_MON) == 0)
continue;
if (strcmp(idle_tbl[i].id_name, "amdc1e") == 0 &&
cpu_ident_amdc1e == 0)
if (strcmp(idle_tbl[i].id_name, "acpi") == 0 &&
cpu_idle_hook == NULL)
continue;
p += sprintf(p, "%s, ", idle_tbl[i].id_name);
p += sprintf(p, "%s%s", p != avail ? ", " : "",
idle_tbl[i].id_name);
}
error = sysctl_handle_string(oidp, avail, 0, req);
free(avail, M_TEMP);
return (error);
}
SYSCTL_PROC(_machdep, OID_AUTO, idle_available, CTLTYPE_STRING | CTLFLAG_RD,
0, 0, idle_sysctl_available, "A", "list of available idle functions");
static int
idle_sysctl(SYSCTL_HANDLER_ARGS)
{
@ -823,8 +829,8 @@ idle_sysctl(SYSCTL_HANDLER_ARGS)
if (strstr(idle_tbl[i].id_name, "mwait") &&
(cpu_feature2 & CPUID2_MON) == 0)
continue;
if (strcmp(idle_tbl[i].id_name, "amdc1e") == 0 &&
cpu_ident_amdc1e == 0)
if (strcmp(idle_tbl[i].id_name, "acpi") == 0 &&
cpu_idle_hook == NULL)
continue;
if (strcmp(idle_tbl[i].id_name, buf))
continue;
@ -834,9 +840,6 @@ idle_sysctl(SYSCTL_HANDLER_ARGS)
return (EINVAL);
}
SYSCTL_PROC(_machdep, OID_AUTO, idle_available, CTLTYPE_STRING | CTLFLAG_RD,
0, 0, idle_sysctl_available, "A", "list of available idle functions");
SYSCTL_PROC(_machdep, OID_AUTO, idle, CTLTYPE_STRING | CTLFLAG_RW, 0, 0,
idle_sysctl, "A", "currently selected idle function");
@ -1089,6 +1092,9 @@ extern inthand_t
IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align),
IDTVEC(xmm), IDTVEC(dblfault),
#ifdef KDTRACE_HOOKS
IDTVEC(dtrace_ret),
#endif
IDTVEC(fast_syscall), IDTVEC(fast_syscall32);
#ifdef DDB
@ -1617,6 +1623,9 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
setidt(IDT_AC, &IDTVEC(align), SDT_SYSIGT, SEL_KPL, 0);
setidt(IDT_MC, &IDTVEC(mchk), SDT_SYSIGT, SEL_KPL, 0);
setidt(IDT_XF, &IDTVEC(xmm), SDT_SYSIGT, SEL_KPL, 0);
#ifdef KDTRACE_HOOKS
setidt(IDT_DTRACE_RET, &IDTVEC(dtrace_ret), SDT_SYSIGT, SEL_UPL, 0);
#endif
r_idt.rd_limit = sizeof(idt0) - 1;
r_idt.rd_base = (long) idt;
@ -1736,8 +1745,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
}
#endif
if (cpu_probe_amdc1e())
cpu_idle_fn = cpu_idle_amdc1e;
cpu_probe_amdc1e();
/* Location of kernel stack for locore */
return ((u_int64_t)thread0.td_pcb);
@ -1792,7 +1800,7 @@ makectx(struct trapframe *tf, struct pcb *pcb)
pcb->pcb_rbp = tf->tf_rbp;
pcb->pcb_rbx = tf->tf_rbx;
pcb->pcb_rip = tf->tf_rip;
pcb->pcb_rsp = (ISPL(tf->tf_cs)) ? tf->tf_rsp : (long)(tf + 1) - 8;
pcb->pcb_rsp = tf->tf_rsp;
}
int

View file

@ -118,7 +118,6 @@ u_long *ipi_invlcache_counts[MAXCPU];
u_long *ipi_rendezvous_counts[MAXCPU];
u_long *ipi_lazypmap_counts[MAXCPU];
static u_long *ipi_hardclock_counts[MAXCPU];
static u_long *ipi_statclock_counts[MAXCPU];
#endif
extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32);
@ -127,7 +126,6 @@ extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32);
* Local data and functions.
*/
static cpumask_t logical_cpus;
static volatile cpumask_t ipi_nmi_pending;
/* used to hold the AP's until we are ready to release them */
@ -153,8 +151,8 @@ int apic_cpuids[MAX_APIC_ID + 1];
static volatile u_int cpu_ipi_pending[MAXCPU];
static u_int boot_address;
static int cpu_logical;
static int cpu_cores;
static int cpu_logical; /* logical cpus per core */
static int cpu_cores; /* cores per package */
static void assign_cpu_ids(void);
static void set_interrupt_apic_ids(void);
@ -162,8 +160,8 @@ static int start_all_aps(void);
static int start_ap(int apic_id);
static void release_aps(void *dummy);
static cpumask_t hlt_logical_cpus;
static cpumask_t hyperthreading_cpus;
static int hlt_logical_cpus;
static u_int hyperthreading_cpus; /* logical cpus sharing L1 cache */
static cpumask_t hyperthreading_cpus_mask;
static int hyperthreading_allowed = 1;
static struct sysctl_ctx_list logical_cpu_clist;
@ -176,25 +174,106 @@ mem_range_AP_init(void)
mem_range_softc.mr_op->initAP(&mem_range_softc);
}
static void
topo_probe_amd(void)
{
/* AMD processors do not support HTT. */
cpu_cores = (amd_feature2 & AMDID2_CMP) != 0 ?
(cpu_procinfo2 & AMDID_CMP_CORES) + 1 : 1;
cpu_logical = 1;
}
/*
* Round up to the next power of two, if necessary, and then
* take log2.
* Returns -1 if argument is zero.
*/
static __inline int
mask_width(u_int x)
{
return (fls(x << (1 - powerof2(x))) - 1);
}
static void
topo_probe_0x4(void)
{
u_int p[4];
int pkg_id_bits;
int core_id_bits;
int max_cores;
int max_logical;
int id;
/* Both zero and one here mean one logical processor per package. */
max_logical = (cpu_feature & CPUID_HTT) != 0 ?
(cpu_procinfo & CPUID_HTT_CORES) >> 16 : 1;
if (max_logical <= 1)
return;
/*
* Because of uniformity assumption we examine only
* those logical processors that belong to the same
* package as BSP. Further, we count number of
* logical processors that belong to the same core
* as BSP thus deducing number of threads per core.
*/
cpuid_count(0x04, 0, p);
max_cores = ((p[0] >> 26) & 0x3f) + 1;
core_id_bits = mask_width(max_logical/max_cores);
if (core_id_bits < 0)
return;
pkg_id_bits = core_id_bits + mask_width(max_cores);
for (id = 0; id <= MAX_APIC_ID; id++) {
/* Check logical CPU availability. */
if (!cpu_info[id].cpu_present || cpu_info[id].cpu_disabled)
continue;
/* Check if logical CPU has the same package ID. */
if ((id >> pkg_id_bits) != (boot_cpu_id >> pkg_id_bits))
continue;
cpu_cores++;
/* Check if logical CPU has the same package and core IDs. */
if ((id >> core_id_bits) == (boot_cpu_id >> core_id_bits))
cpu_logical++;
}
cpu_cores /= cpu_logical;
hyperthreading_cpus = cpu_logical;
}
static void
topo_probe_0xb(void)
{
int logical;
int p[4];
u_int p[4];
int bits;
int type;
int cnt;
int i;
int logical;
int type;
int x;
/* We only support two levels for now. */
/* We only support three levels for now. */
for (i = 0; i < 3; i++) {
cpuid_count(0x0B, i, p);
cpuid_count(0x0b, i, p);
/* Fall back if CPU leaf 11 doesn't really exist. */
if (i == 0 && p[1] == 0) {
topo_probe_0x4();
return;
}
bits = p[0] & 0x1f;
logical = p[1] &= 0xffff;
type = (p[2] >> 8) & 0xff;
if (type == 0 || logical == 0)
break;
/*
* Because of uniformity assumption we examine only
* those logical processors that belong to the same
* package as BSP.
*/
for (cnt = 0, x = 0; x <= MAX_APIC_ID; x++) {
if (!cpu_info[x].cpu_present ||
cpu_info[x].cpu_disabled)
@ -212,76 +291,16 @@ topo_probe_0xb(void)
cpu_cores /= cpu_logical;
}
static void
topo_probe_0x4(void)
{
u_int threads_per_cache, p[4];
u_int htt, cmp;
int i;
htt = cmp = 1;
/*
* If this CPU supports HTT or CMP then mention the
* number of physical/logical cores it contains.
*/
if (cpu_feature & CPUID_HTT)
htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
if (cpu_vendor_id == CPU_VENDOR_AMD && (amd_feature2 & AMDID2_CMP))
cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
else if (cpu_vendor_id == CPU_VENDOR_INTEL && (cpu_high >= 4)) {
cpuid_count(4, 0, p);
if ((p[0] & 0x1f) != 0)
cmp = ((p[0] >> 26) & 0x3f) + 1;
}
cpu_cores = cmp;
cpu_logical = htt / cmp;
/* Setup the initial logical CPUs info. */
if (cpu_feature & CPUID_HTT)
logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
/*
* Work out if hyperthreading is *really* enabled. This
* is made really ugly by the fact that processors lie: Dual
* core processors claim to be hyperthreaded even when they're
* not, presumably because they want to be treated the same
* way as HTT with respect to per-cpu software licensing.
* At the time of writing (May 12, 2005) the only hyperthreaded
* cpus are from Intel, and Intel's dual-core processors can be
* identified via the "deterministic cache parameters" cpuid
* calls.
*/
/*
* First determine if this is an Intel processor which claims
* to have hyperthreading support.
*/
if ((cpu_feature & CPUID_HTT) && cpu_vendor_id == CPU_VENDOR_INTEL) {
/*
* If the "deterministic cache parameters" cpuid calls
* are available, use them.
*/
if (cpu_high >= 4) {
/* Ask the processor about the L1 cache. */
for (i = 0; i < 1; i++) {
cpuid_count(4, i, p);
threads_per_cache = ((p[0] & 0x3ffc000) >> 14) + 1;
if (hyperthreading_cpus < threads_per_cache)
hyperthreading_cpus = threads_per_cache;
if ((p[0] & 0x1f) == 0)
break;
}
}
/*
* If the deterministic cache parameters are not
* available, or if no caches were reported to exist,
* just accept what the HTT flag indicated.
*/
if (hyperthreading_cpus == 0)
hyperthreading_cpus = logical_cpus;
}
}
/*
* Both topology discovery code and code that consumes topology
* information assume top-down uniformity of the topology.
* That is, all physical packages must be identical and each
* core in a package must have the same number of threads.
* Topology information is queried only on BSP, on which this
* code runs and for which it can query CPUID information.
* Then topology is extrapolated on all packages using the
* uniformity assumption.
*/
static void
topo_probe(void)
{
@ -290,13 +309,31 @@ topo_probe(void)
if (cpu_topo_probed)
return;
logical_cpus = logical_cpus_mask = 0;
if (cpu_high >= 0xb)
topo_probe_0xb();
else if (cpu_high)
topo_probe_0x4();
logical_cpus_mask = 0;
if (cpu_vendor_id == CPU_VENDOR_AMD)
topo_probe_amd();
else if (cpu_vendor_id == CPU_VENDOR_INTEL) {
/*
* See Intel(R) 64 Architecture Processor
* Topology Enumeration article for details.
*
* Note that 0x1 <= cpu_high < 4 case should be
* compatible with topo_probe_0x4() logic when
* CPUID.1:EBX[23:16] > 0 (cpu_cores will be 1)
* or it should trigger the fallback otherwise.
*/
if (cpu_high >= 0xb)
topo_probe_0xb();
else if (cpu_high >= 0x1)
topo_probe_0x4();
}
/*
* Fallback: assume each logical CPU is in separate
* physical package. That is, no multi-core, no SMT.
*/
if (cpu_cores == 0)
cpu_cores = mp_ncpus > 0 ? mp_ncpus : 1;
cpu_cores = 1;
if (cpu_logical == 0)
cpu_logical = 1;
cpu_topo_probed = 1;
@ -676,7 +713,8 @@ init_secondary(void)
printf("SMP: AP CPU #%d Launched!\n", PCPU_GET(cpuid));
/* Determine if we are a logical CPU. */
if (logical_cpus > 1 && PCPU_GET(apic_id) % logical_cpus != 0)
/* XXX Calculation depends on cpu_logical being a power of 2, e.g. 2 */
if (cpu_logical > 1 && PCPU_GET(apic_id) % cpu_logical != 0)
logical_cpus_mask |= PCPU_GET(cpumask);
/* Determine if we are a hyperthread. */
@ -1196,16 +1234,22 @@ smp_masked_invlpg_range(cpumask_t mask, vm_offset_t addr1, vm_offset_t addr2)
void
ipi_bitmap_handler(struct trapframe frame)
{
struct trapframe *oldframe;
struct thread *td;
int cpu = PCPU_GET(cpuid);
u_int ipi_bitmap;
critical_enter();
td = curthread;
td->td_intr_nesting_level++;
oldframe = td->td_intr_frame;
td->td_intr_frame = &frame;
ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]);
if (ipi_bitmap & (1 << IPI_PREEMPT)) {
#ifdef COUNT_IPIS
(*ipi_preempt_counts[cpu])++;
#endif
sched_preempt(curthread);
sched_preempt(td);
}
if (ipi_bitmap & (1 << IPI_AST)) {
#ifdef COUNT_IPIS
@ -1217,14 +1261,11 @@ ipi_bitmap_handler(struct trapframe frame)
#ifdef COUNT_IPIS
(*ipi_hardclock_counts[cpu])++;
#endif
hardclockintr(&frame);
}
if (ipi_bitmap & (1 << IPI_STATCLOCK)) {
#ifdef COUNT_IPIS
(*ipi_statclock_counts[cpu])++;
#endif
statclockintr(&frame);
hardclockintr();
}
td->td_intr_frame = oldframe;
td->td_intr_nesting_level--;
critical_exit();
}
/*
@ -1579,8 +1620,6 @@ mp_ipi_intrcnt(void *dummy)
intrcnt_add(buf, &ipi_lazypmap_counts[i]);
snprintf(buf, sizeof(buf), "cpu%d:hardclock", i);
intrcnt_add(buf, &ipi_hardclock_counts[i]);
snprintf(buf, sizeof(buf), "cpu%d:statclock", i);
intrcnt_add(buf, &ipi_statclock_counts[i]);
}
}
SYSINIT(mp_ipi_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, mp_ipi_intrcnt, NULL);

View file

@ -83,7 +83,7 @@ static int nexus_probe(device_t);
static int nexus_attach(device_t);
static int nexus_print_all_resources(device_t dev);
static int nexus_print_child(device_t, device_t);
static device_t nexus_add_child(device_t bus, int order, const char *name,
static device_t nexus_add_child(device_t bus, u_int order, const char *name,
int unit);
static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
u_long, u_long, u_long, u_int);
@ -293,7 +293,7 @@ nexus_print_child(device_t bus, device_t child)
}
static device_t
nexus_add_child(device_t bus, int order, const char *name, int unit)
nexus_add_child(device_t bus, u_int order, const char *name, int unit)
{
device_t child;
struct nexus_device *ndev;

View file

@ -620,7 +620,8 @@ pmap_init_pat(void)
if (sysenv != NULL) {
if (strncmp(sysenv, "MacBook5,1", 10) == 0 ||
strncmp(sysenv, "MacBookPro5,5", 13) == 0 ||
strncmp(sysenv, "Macmini3,1", 10) == 0)
strncmp(sysenv, "Macmini3,1", 10) == 0 ||
strncmp(sysenv, "iMac9,1", 7) == 0)
pat_works = 0;
freeenv(sysenv);
}
@ -1162,26 +1163,33 @@ pmap_is_current(pmap_t pmap)
vm_paddr_t
pmap_extract(pmap_t pmap, vm_offset_t va)
{
vm_paddr_t rtval;
pdp_entry_t *pdpe;
pd_entry_t *pde;
pt_entry_t *pte;
pd_entry_t pde, *pdep;
vm_paddr_t pa;
rtval = 0;
pa = 0;
PMAP_LOCK(pmap);
pdep = pmap_pde(pmap, va);
if (pdep != NULL) {
pde = *pdep;
if (pde) {
if ((pde & PG_PS) != 0)
rtval = (pde & PG_PS_FRAME) | (va & PDRMASK);
else {
pte = pmap_pde_to_pte(pdep, va);
rtval = (*pte & PG_FRAME) | (va & PAGE_MASK);
pdpe = pmap_pdpe(pmap, va);
if (pdpe != NULL && (*pdpe & PG_V) != 0) {
if ((*pdpe & PG_PS) != 0)
pa = (*pdpe & PG_PS_FRAME) | (va & PDPMASK);
else {
pde = pmap_pdpe_to_pde(pdpe, va);
if ((*pde & PG_V) != 0) {
if ((*pde & PG_PS) != 0) {
pa = (*pde & PG_PS_FRAME) |
(va & PDRMASK);
} else {
pte = pmap_pde_to_pte(pde, va);
pa = (*pte & PG_FRAME) |
(va & PAGE_MASK);
}
}
}
}
PMAP_UNLOCK(pmap);
return (rtval);
return (pa);
}
/*

View file

@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include "opt_isa.h"
#include "opt_kdb.h"
#include "opt_kdtrace.h"
#include "opt_ktrace.h"
#include <sys/param.h>
#include <sys/bus.h>
@ -70,9 +69,6 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <sys/uio.h>
#include <sys/vmmeter.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
#ifdef HWPMC_HOOKS
#include <sys/pmckern.h>
#endif
@ -113,6 +109,13 @@ dtrace_doubletrap_func_t dtrace_doubletrap_func;
* implementation opaque.
*/
systrace_probe_func_t systrace_probe_func;
/*
* These hooks are necessary for the pid, usdt and fasttrap providers.
*/
dtrace_fasttrap_probe_ptr_t dtrace_fasttrap_probe_ptr;
dtrace_pid_probe_ptr_t dtrace_pid_probe_ptr;
dtrace_return_probe_ptr_t dtrace_return_probe_ptr;
#endif
extern void trap(struct trapframe *frame);
@ -243,6 +246,55 @@ trap(struct trapframe *frame)
if (dtrace_trap_func != NULL)
if ((*dtrace_trap_func)(frame, type))
goto out;
if (type == T_DTRACE_PROBE || type == T_DTRACE_RET ||
type == T_BPTFLT) {
struct reg regs;
regs.r_r15 = frame->tf_r15;
regs.r_r14 = frame->tf_r14;
regs.r_r13 = frame->tf_r13;
regs.r_r12 = frame->tf_r12;
regs.r_r11 = frame->tf_r11;
regs.r_r10 = frame->tf_r10;
regs.r_r9 = frame->tf_r9;
regs.r_r8 = frame->tf_r8;
regs.r_rdi = frame->tf_rdi;
regs.r_rsi = frame->tf_rsi;
regs.r_rbp = frame->tf_rbp;
regs.r_rbx = frame->tf_rbx;
regs.r_rdx = frame->tf_rdx;
regs.r_rcx = frame->tf_rcx;
regs.r_rax = frame->tf_rax;
regs.r_rip = frame->tf_rip;
regs.r_cs = frame->tf_cs;
regs.r_rflags = frame->tf_rflags;
regs.r_rsp = frame->tf_rsp;
regs.r_ss = frame->tf_ss;
if (frame->tf_flags & TF_HASSEGS) {
regs.r_ds = frame->tf_ds;
regs.r_es = frame->tf_es;
regs.r_fs = frame->tf_fs;
regs.r_gs = frame->tf_gs;
} else {
regs.r_ds = 0;
regs.r_es = 0;
regs.r_fs = 0;
regs.r_gs = 0;
}
if (type == T_DTRACE_PROBE &&
dtrace_fasttrap_probe_ptr != NULL &&
dtrace_fasttrap_probe_ptr(&regs) == 0)
goto out;
if (type == T_BPTFLT &&
dtrace_pid_probe_ptr != NULL &&
dtrace_pid_probe_ptr(&regs) == 0)
goto out;
if (type == T_DTRACE_RET &&
dtrace_return_probe_ptr != NULL &&
dtrace_return_probe_ptr(&regs) == 0)
goto out;
}
#endif
if ((frame->tf_rflags & PSL_I) == 0) {

View file

@ -55,7 +55,6 @@ options STACK # stack(9) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options P1003_1B_SEMAPHORES # POSIX-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
@ -112,6 +111,7 @@ device hptiop # Highpoint RocketRaid 3xxx series
device isp # Qlogic family
#device ispfw # Firmware for QLogic HBAs- normally a module
device mpt # LSI-Logic MPT-Fusion
device mps # LSI-Logic MPT-Fusion 2
#device ncr # NCR/Symbios Logic
device sym # NCR/Symbios Logic (newer chipsets + those of `ncr')
device trm # Tekram DC395U/UW/F DC315U adapters

View file

@ -421,6 +421,7 @@ options SAFE_RNDTEST # enable rndtest support
# vpd: Vital Product Data kernel interface
# asmc: Apple System Management Controller
# si: Specialix International SI/XIO or SX intelligent serial card
# tpm: Trusted Platform Module
# Notes on the Specialix SI/XIO driver:
# The host card is memory, not IO mapped.
@ -436,6 +437,7 @@ device smbios
device vpd
device asmc
#device si
device tpm
#
# Laptop/Notebook options:

View file

@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$");
#include "opt_clock.h"
#include "opt_cpu.h"
#include "opt_isa.h"
#include "opt_ktrace.h"
#include <sys/param.h>
#include <sys/bus.h>
@ -65,9 +64,6 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <sys/uio.h>
#include <sys/vmmeter.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
#include <security/audit/audit.h>
#include <vm/vm.h>

View file

@ -123,8 +123,7 @@
#define IPI_AST 0 /* Generate software trap. */
#define IPI_PREEMPT 1
#define IPI_HARDCLOCK 2
#define IPI_STATCLOCK 3
#define IPI_BITMAP_LAST IPI_STATCLOCK
#define IPI_BITMAP_LAST IPI_HARDCLOCK
#define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST)
#define IPI_STOP (APIC_IPI_INTS + 7) /* Stop CPU until restarted. */

View file

@ -421,40 +421,40 @@ invlpg(u_long addr)
__asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory");
}
static __inline u_int
static __inline u_short
rfs(void)
{
u_int sel;
__asm __volatile("mov %%fs,%0" : "=rm" (sel));
u_short sel;
__asm __volatile("movw %%fs,%0" : "=rm" (sel));
return (sel);
}
static __inline u_int
static __inline u_short
rgs(void)
{
u_int sel;
__asm __volatile("mov %%gs,%0" : "=rm" (sel));
u_short sel;
__asm __volatile("movw %%gs,%0" : "=rm" (sel));
return (sel);
}
static __inline u_int
static __inline u_short
rss(void)
{
u_int sel;
__asm __volatile("mov %%ss,%0" : "=rm" (sel));
u_short sel;
__asm __volatile("movw %%ss,%0" : "=rm" (sel));
return (sel);
}
static __inline void
load_ds(u_int sel)
load_ds(u_short sel)
{
__asm __volatile("mov %0,%%ds" : : "rm" (sel));
__asm __volatile("movw %0,%%ds" : : "rm" (sel));
}
static __inline void
load_es(u_int sel)
load_es(u_short sel)
{
__asm __volatile("mov %0,%%es" : : "rm" (sel));
__asm __volatile("movw %0,%%es" : : "rm" (sel));
}
static __inline void
@ -476,10 +476,10 @@ cpu_mwait(int extensions, int hints)
#define MSR_FSBASE 0xc0000100
#endif
static __inline void
load_fs(u_int sel)
load_fs(u_short sel)
{
/* Preserve the fsbase value across the selector load */
__asm __volatile("rdmsr; mov %0,%%fs; wrmsr"
__asm __volatile("rdmsr; movw %0,%%fs; wrmsr"
: : "rm" (sel), "c" (MSR_FSBASE) : "eax", "edx");
}
@ -487,28 +487,28 @@ load_fs(u_int sel)
#define MSR_GSBASE 0xc0000101
#endif
static __inline void
load_gs(u_int sel)
load_gs(u_short sel)
{
/*
* Preserve the gsbase value across the selector load.
* Note that we have to disable interrupts because the gsbase
* being trashed happens to be the kernel gsbase at the time.
*/
__asm __volatile("pushfq; cli; rdmsr; mov %0,%%gs; wrmsr; popfq"
__asm __volatile("pushfq; cli; rdmsr; movw %0,%%gs; wrmsr; popfq"
: : "rm" (sel), "c" (MSR_GSBASE) : "eax", "edx");
}
#else
/* Usable by userland */
static __inline void
load_fs(u_int sel)
load_fs(u_short sel)
{
__asm __volatile("mov %0,%%fs" : : "rm" (sel));
__asm __volatile("movw %0,%%fs" : : "rm" (sel));
}
static __inline void
load_gs(u_int sel)
load_gs(u_short sel)
{
__asm __volatile("mov %0,%%gs" : : "rm" (sel));
__asm __volatile("movw %0,%%gs" : : "rm" (sel));
}
#endif
@ -692,8 +692,8 @@ void load_dr4(u_int64_t dr4);
void load_dr5(u_int64_t dr5);
void load_dr6(u_int64_t dr6);
void load_dr7(u_int64_t dr7);
void load_fs(u_int sel);
void load_gs(u_int sel);
void load_fs(u_short sel);
void load_gs(u_short sel);
void ltr(u_short sel);
void outb(u_int port, u_char data);
void outl(u_int port, u_int data);

View file

@ -88,8 +88,14 @@ __ElfType(Auxinfo);
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_EXECPATH 15 /* Path to the executable. */
#define AT_CANARY 16 /* Canary for SSP */
#define AT_CANARYLEN 17 /* Length of the canary. */
#define AT_OSRELDATE 18 /* OSRELDATE. */
#define AT_NCPUS 19 /* Number of CPUs. */
#define AT_PAGESIZES 20 /* Pagesizes. */
#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
#define AT_COUNT 16 /* Count of defined aux entry types. */
#define AT_COUNT 22 /* Count of defined aux entry types. */
/*
* Relocation types.

View file

@ -214,6 +214,7 @@ struct region_descriptor {
#define IDT_XF 19 /* #XF: SIMD Floating-Point Exception */
#define IDT_IO_INTS NRSVIDT /* Base of IDT entries for I/O interrupts. */
#define IDT_SYSCALL 0x80 /* System Call Interrupt Vector */
#define IDT_DTRACE_RET 0x92 /* DTrace pid provider Interrupt Vector */
/*
* Entries in the Global Descriptor Table (GDT)

View file

@ -126,6 +126,7 @@
#define CPUID2_CX16 0x00002000
#define CPUID2_XTPR 0x00004000
#define CPUID2_PDCM 0x00008000
#define CPUID2_PCID 0x00020000
#define CPUID2_DCA 0x00040000
#define CPUID2_SSE41 0x00080000
#define CPUID2_SSE42 0x00100000

View file

@ -62,6 +62,8 @@
#define T_MCHK 28 /* machine check trap */
#define T_XMMFLT 29 /* SIMD floating-point exception */
#define T_RESERVED 30 /* reserved (unknown) */
#define T_DTRACE_RET 31 /* DTrace pid return */
#define T_DTRACE_PROBE 32 /* DTrace fasttrap probe */
/* XXX most of the following codes aren't used, but could be. */

View file

@ -205,7 +205,7 @@
* is the total KVA space allocated for kmem_map.
*/
#ifndef VM_KMEM_SIZE_SCALE
#define VM_KMEM_SIZE_SCALE (3)
#define VM_KMEM_SIZE_SCALE (1)
#endif
/*

View file

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/amd64/linux32/syscalls.master 210431 2010-07-23 21:30:33Z kib
* created from FreeBSD: head/sys/amd64/linux32/syscalls.master 213544 2010-10-08 07:18:44Z kib
*/
#ifndef _LINUX_SYSPROTO_H_

View file

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/amd64/linux32/syscalls.master 210431 2010-07-23 21:30:33Z kib
* created from FreeBSD: head/sys/amd64/linux32/syscalls.master 213544 2010-10-08 07:18:44Z kib
*/
#define LINUX_SYS_exit 1

View file

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/amd64/linux32/syscalls.master 210431 2010-07-23 21:30:33Z kib
* created from FreeBSD: head/sys/amd64/linux32/syscalls.master 213544 2010-10-08 07:18:44Z kib
*/
#include "opt_compat.h"
@ -267,7 +267,7 @@ struct sysent linux_sysent[] = {
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 245 = linux_io_setup */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 246 = linux_io_destroy */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 247 = linux_io_getevents */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 248 = inux_io_submit */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 248 = linux_io_submit */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 249 = linux_io_cancel */
{ 0, (sy_call_t *)linux_fadvise64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 250 = linux_fadvise64 */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 251 = */

View file

@ -1210,4 +1210,4 @@ static moduledata_t linux_elf_mod = {
0
};
DECLARE_MODULE(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
DECLARE_MODULE_TIED(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);

View file

@ -416,7 +416,7 @@
245 AUE_NULL UNIMPL linux_io_setup
246 AUE_NULL UNIMPL linux_io_destroy
247 AUE_NULL UNIMPL linux_io_getevents
248 AUE_NULL UNIMPL inux_io_submit
248 AUE_NULL UNIMPL linux_io_submit
249 AUE_NULL UNIMPL linux_io_cancel
250 AUE_NULL STD { int linux_fadvise64(void); }
251 AUE_NULL UNIMPL

View file

@ -397,7 +397,7 @@ struct cpu_functions sheeva_cpufuncs = {
cpufunc_nullop, /* flush_brnchtgt_C */
(void *)cpufunc_nullop, /* flush_brnchtgt_E */
(void *)cpufunc_nullop, /* sleep */
sheeva_cpu_sleep, /* sleep */
/* Soft functions */
@ -1076,6 +1076,9 @@ set_cpufuncs()
FC_DCACHE_STREAM_EN | FC_WR_ALLOC_EN |
FC_BRANCH_TARG_BUF_DIS | FC_L2CACHE_EN);
}
/* Use powersave on this CPU. */
cpu_do_powersave = 1;
} else
cpufuncs = armv5_ec_cpufuncs;

View file

@ -392,3 +392,10 @@ ENTRY(sheeva_control_ext)
mcrne p15, 1, r2, c15, c1, 0 /* Write new control register */
mov r0, r3 /* Return old value */
RET
ENTRY(sheeva_cpu_sleep)
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */
mcr p15, 0, r0, c7, c0, 4 /* Wait for interrupt */
mov pc, lr

View file

@ -74,7 +74,7 @@ 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 device_t nexus_add_child(device_t, u_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,
@ -166,7 +166,7 @@ nexus_print_child(device_t bus, device_t child)
}
static device_t
nexus_add_child(device_t bus, int order, const char *name, int unit)
nexus_add_child(device_t bus, u_int order, const char *name, int unit)
{
device_t child;
struct nexus_device *ndev;

View file

@ -3158,8 +3158,6 @@ pmap_remove_all(vm_page_t m)
*ptep = 0;
PTE_SYNC_CURRENT(pv->pv_pmap, ptep);
pmap_free_l2_bucket(pv->pv_pmap, l2b, 1);
if (pv->pv_flags & PVF_WIRED)
pv->pv_pmap->pm_stats.wired_count--;
pv->pv_pmap->pm_stats.resident_count--;
flags |= pv->pv_flags;
}

View file

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2005 Olivier Houchard. All rights reserved.
* Copyright (c) 2010 Greg Ansley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -43,14 +44,23 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_pmcvar.h>
#include <arm/at91/at91_aicreg.h>
static struct at91_softc *at91_softc;
static void at91_eoi(void *);
extern const struct pmap_devmap at91_devmap[];
uint32_t at91_chip_id;
#ifdef AT91C_MASTER_CLOCK
uint32_t at91_master_clock = AT91C_MASTER_CLOCK;
#else
uint32_t at91_master_clock;
#endif
static int
at91_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
@ -99,6 +109,19 @@ at91_barrier(void *t, bus_space_handle_t bsh, bus_size_t size, bus_size_t b,
{
}
struct arm32_dma_range *
bus_dma_get_range(void)
{
return (NULL);
}
int
bus_dma_get_range_nb(void)
{
return (0);
}
bs_protos(generic);
bs_protos(generic_armv4);
@ -212,6 +235,7 @@ struct bus_space at91_bs_tag = {
static int
at91_probe(device_t dev)
{
device_set_desc(dev, "AT91 device bus");
arm_post_filter = at91_eoi;
return (0);
@ -224,324 +248,38 @@ at91_identify(driver_t *drv, device_t parent)
BUS_ADD_CHILD(parent, 0, "atmelarm", 0);
}
struct arm32_dma_range *
bus_dma_get_range(void)
{
return (NULL);
}
int
bus_dma_get_range_nb(void)
{
return (0);
}
extern void irq_entry(void);
static void
at91_add_child(device_t dev, int prio, const char *name, int unit,
bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
{
device_t kid;
struct at91_ivar *ivar;
kid = device_add_child_ordered(dev, prio, name, unit);
if (kid == NULL) {
printf("Can't add child %s%d ordered\n", name, unit);
return;
}
ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
if (ivar == NULL) {
device_delete_child(dev, kid);
printf("Can't add alloc ivar\n");
return;
}
device_set_ivars(kid, ivar);
resource_list_init(&ivar->resources);
if (irq0 != -1)
bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
if (irq1 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
if (irq2 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
if (addr != 0)
bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
}
struct cpu_devs
{
const char *name;
int unit;
bus_addr_t mem_base;
bus_size_t mem_len;
int irq0;
int irq1;
int irq2;
};
struct cpu_devs at91rm9200_devs[] =
{
// All the "system" devices
{
"at91_st", 0,
AT91RM92_BASE + AT91RM92_ST_BASE, AT91RM92_ST_SIZE,
AT91RM92_IRQ_SYSTEM
},
{
"at91_pio", 0,
AT91RM92_BASE + AT91RM92_PIOA_BASE, AT91RM92_PIO_SIZE,
AT91RM92_IRQ_SYSTEM
},
{
"at91_pio", 1,
AT91RM92_BASE + AT91RM92_PIOB_BASE, AT91RM92_PIO_SIZE,
AT91RM92_IRQ_SYSTEM
},
{
"at91_pio", 2,
AT91RM92_BASE + AT91RM92_PIOC_BASE, AT91RM92_PIO_SIZE,
AT91RM92_IRQ_SYSTEM
},
{
"at91_pio", 3,
AT91RM92_BASE + AT91RM92_PIOD_BASE, AT91RM92_PIO_SIZE,
AT91RM92_IRQ_SYSTEM
},
{
"at91_pmc", 0,
AT91RM92_BASE + AT91RM92_PMC_BASE, AT91RM92_PMC_SIZE,
AT91RM92_IRQ_SYSTEM
},
{
"at91_aic", 0,
AT91RM92_BASE + AT91RM92_AIC_BASE, AT91RM92_AIC_SIZE,
0 // Interrupt controller has no interrupts!
},
{
"at91_rtc", 0,
AT91RM92_BASE + AT91RM92_RTC_BASE, AT91RM92_RTC_SIZE,
AT91RM92_IRQ_SYSTEM
},
{
"at91_mc", 0,
AT91RM92_BASE + AT91RM92_MC_BASE, AT91RM92_MC_SIZE,
AT91RM92_IRQ_SYSTEM
},
// All other devices
{
"at91_tc", 0,
AT91RM92_BASE + AT91RM92_TC0_BASE, AT91RM92_TC_SIZE,
AT91RM92_IRQ_TC0, AT91RM92_IRQ_TC1, AT91RM92_IRQ_TC2
},
{
"at91_tc", 1,
AT91RM92_BASE + AT91RM92_TC1_BASE, AT91RM92_TC_SIZE,
AT91RM92_IRQ_TC3, AT91RM92_IRQ_TC4, AT91RM92_IRQ_TC5
},
{
"at91_udp", 0,
AT91RM92_BASE + AT91RM92_UDP_BASE, AT91RM92_UDP_SIZE,
AT91RM92_IRQ_UDP, AT91RM92_IRQ_PIOB
},
{
"at91_mci", 0,
AT91RM92_BASE + AT91RM92_MCI_BASE, AT91RM92_MCI_SIZE,
AT91RM92_IRQ_MCI
},
{
"at91_twi", 0,
AT91RM92_BASE + AT91RM92_TWI_BASE, AT91RM92_TWI_SIZE,
AT91RM92_IRQ_TWI
},
{
"ate", 0,
AT91RM92_BASE + AT91RM92_EMAC_BASE, AT91RM92_EMAC_SIZE,
AT91RM92_IRQ_EMAC
},
#ifndef SKYEYE_WORKAROUNDS
{
"uart", 0,
AT91RM92_BASE + AT91RM92_DBGU_BASE, AT91RM92_DBGU_SIZE,
AT91RM92_IRQ_SYSTEM
},
{
"uart", 1,
AT91RM92_BASE + AT91RM92_USART0_BASE, AT91RM92_USART_SIZE,
AT91RM92_IRQ_USART0
},
{
"uart", 2,
AT91RM92_BASE + AT91RM92_USART1_BASE, AT91RM92_USART_SIZE,
AT91RM92_IRQ_USART1
},
{
"uart", 3,
AT91RM92_BASE + AT91RM92_USART2_BASE, AT91RM92_USART_SIZE,
AT91RM92_IRQ_USART2
},
{
"uart", 4,
AT91RM92_BASE + AT91RM92_USART3_BASE, AT91RM92_USART_SIZE,
AT91RM92_IRQ_USART3
},
#else
{
"uart", 0,
AT91RM92_BASE + AT91RM92_USART0_BASE, AT91RM92_USART_SIZE,
AT91RM92_IRQ_USART0
},
#endif
{
"at91_ssc", 0,
AT91RM92_BASE + AT91RM92_SSC0_BASE, AT91RM92_SSC_SIZE,
AT91RM92_IRQ_SSC0
},
{
"at91_ssc", 1,
AT91RM92_BASE + AT91RM92_SSC1_BASE, AT91RM92_SSC_SIZE,
AT91RM92_IRQ_SSC1
},
{
"at91_ssc", 2,
AT91RM92_BASE + AT91RM92_SSC2_BASE, AT91RM92_SSC_SIZE,
AT91RM92_IRQ_SSC2
},
{
"spi", 0,
AT91RM92_BASE + AT91RM92_SPI_BASE, AT91RM92_SPI_SIZE,
AT91RM92_IRQ_SPI
},
{
"ohci", 0,
AT91RM92_OHCI_BASE, AT91RM92_OHCI_SIZE,
AT91RM92_IRQ_UHP
},
{
"at91_cfata", 0,
AT91RM92_CF_BASE, AT91RM92_CF_SIZE,
-1
},
{ 0, 0, 0, 0, 0 }
};
static void
at91_cpu_add_builtin_children(device_t dev, struct at91_softc *sc)
{
int i;
struct cpu_devs *walker;
// XXX should look at the device id in the DBGU register and
// XXX based on the CPU load in these devices
for (i = 0, walker = at91rm9200_devs; walker->name; i++, walker++) {
at91_add_child(dev, i, walker->name, walker->unit,
walker->mem_base, walker->mem_len, walker->irq0,
walker->irq1, walker->irq2);
}
}
#define NORMDEV 50
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
* These values are the ones Atmel uses for its Linux port, which differ
* a little form the ones that are in the standard distribution. Also,
* the ones marked with 'TWEEK' are different based on experience.
*/
static int irq_prio[32] =
{
7, /* Advanced Interrupt Controller (FIQ) */
7, /* System Peripherals */
1, /* Parallel IO Controller A */
1, /* Parallel IO Controller B */
1, /* Parallel IO Controller C */
1, /* Parallel IO Controller D */
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
5, /* USART 3 */
0, /* Multimedia Card Interface */
2, /* USB Device Port */
4, /* Two-Wire Interface */ /* TWEEK */
5, /* Serial Peripheral Interface */
4, /* Serial Synchronous Controller 0 */
6, /* Serial Synchronous Controller 1 */ /* TWEEK */
4, /* Serial Synchronous Controller 2 */
0, /* Timer Counter 0 */
6, /* Timer Counter 1 */ /* TWEEK */
0, /* Timer Counter 2 */
0, /* Timer Counter 3 */
0, /* Timer Counter 4 */
0, /* Timer Counter 5 */
2, /* USB Host port */
3, /* Ethernet MAC */
0, /* Advanced Interrupt Controller (IRQ0) */
0, /* Advanced Interrupt Controller (IRQ1) */
0, /* Advanced Interrupt Controller (IRQ2) */
0, /* Advanced Interrupt Controller (IRQ3) */
0, /* Advanced Interrupt Controller (IRQ4) */
0, /* Advanced Interrupt Controller (IRQ5) */
0 /* Advanced Interrupt Controller (IRQ6) */
};
static int
at91_attach(device_t dev)
{
struct at91_softc *sc = device_get_softc(dev);
int i;
const struct pmap_devmap *pdevmap;
at91_softc = sc;
sc->sc_st = &at91_bs_tag;
sc->sc_sh = AT91RM92_BASE;
sc->sc_sh = AT91_BASE;
sc->dev = dev;
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_SYS_BASE,
AT91RM92_SYS_SIZE, &sc->sc_sys_sh) != 0)
panic("Enable to map IRQ registers");
sc->sc_irq_rman.rm_type = RMAN_ARRAY;
sc->sc_irq_rman.rm_descr = "AT91 IRQs";
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "AT91 Memory";
if (rman_init(&sc->sc_irq_rman) != 0 ||
rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0)
panic("at91_attach: failed to set up IRQ rman");
if (rman_init(&sc->sc_mem_rman) != 0 ||
rman_manage_region(&sc->sc_mem_rman, 0xdff00000ul,
0xdffffffful) != 0)
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "AT91 Memory";
if (rman_init(&sc->sc_mem_rman) != 0)
panic("at91_attach: failed to set up memory rman");
if (rman_manage_region(&sc->sc_mem_rman, AT91RM92_OHCI_BASE,
AT91RM92_OHCI_BASE + AT91RM92_OHCI_SIZE - 1) != 0)
panic("at91_attach: failed to set up ohci memory");
if (rman_manage_region(&sc->sc_mem_rman, AT91RM92_CF_BASE,
AT91RM92_CF_BASE + AT91RM92_CF_SIZE - 1) != 0)
panic("at91_attach: failed to set up CompactFlash ATA memory");
for (i = 0; i < 32; i++) {
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SVR +
i * 4, i);
/* Priority. */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SMR + i * 4,
irq_prio[i]);
if (i < 8)
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_EOICR,
1);
for ( pdevmap = at91_devmap; pdevmap->pd_va != 0; pdevmap++) {
if (rman_manage_region(&sc->sc_mem_rman, pdevmap->pd_va,
pdevmap->pd_va + pdevmap->pd_size - 1) != 0)
panic("at91_attach: failed to set up memory rman");
}
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SPU, 32);
/* No debug. */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_DCR, 0);
/* Disable and clear all interrupts. */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IDCR, 0xffffffff);
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_ICCR, 0xffffffff);
/* XXX */
/* Disable all interrupts for RTC (0xe24 == RTC_IDR) */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff);
/* DIsable all interrupts for DBGU */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x20c, 0xffffffff);
/* Disable all interrupts for the SDRAM controller */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);
at91_cpu_add_builtin_children(dev, sc);
/* Our device list will be added automatically by the cpu device
* e.g. at91rm9200.c when it is identified. To ensure that the
* CPU and PMC are attached first any other "identified" devices
* call BUS_ADD_CHILD(9) with an "order" of at least 2. */
bus_generic_probe(dev);
bus_generic_attach(dev);
@ -630,11 +368,11 @@ at91_setup_intr(device_t dev, device_t child,
{
struct at91_softc *sc = device_get_softc(dev);
if (rman_get_start(ires) == AT91RM92_IRQ_SYSTEM && filt == NULL)
if (rman_get_start(ires) == sc->sc_irq_system && filt == NULL)
panic("All system interrupt ISRs must be FILTER");
BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
intr, arg, cookiep);
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IECR,
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IECR,
1 << rman_get_start(ires));
return (0);
}
@ -645,7 +383,7 @@ at91_teardown_intr(device_t dev, device_t child, struct resource *res,
{
struct at91_softc *sc = device_get_softc(dev);
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IDCR,
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR,
1 << rman_get_start(res));
return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
}
@ -697,8 +435,7 @@ arm_mask_irq(uintptr_t nb)
{
bus_space_write_4(at91_softc->sc_st,
at91_softc->sc_sys_sh, IC_IDCR, 1 << nb);
at91_softc->sc_aic_sh, IC_IDCR, 1 << nb);
}
int
@ -708,12 +445,12 @@ arm_get_next_irq(int last __unused)
int irq;
irq = bus_space_read_4(at91_softc->sc_st,
at91_softc->sc_sys_sh, IC_IVR);
at91_softc->sc_aic_sh, IC_IVR);
status = bus_space_read_4(at91_softc->sc_st,
at91_softc->sc_sys_sh, IC_ISR);
at91_softc->sc_aic_sh, IC_ISR);
if (status == 0) {
bus_space_write_4(at91_softc->sc_st,
at91_softc->sc_sys_sh, IC_EOICR, 1);
at91_softc->sc_aic_sh, IC_EOICR, 1);
return (-1);
}
return (irq);
@ -724,16 +461,15 @@ arm_unmask_irq(uintptr_t nb)
{
bus_space_write_4(at91_softc->sc_st,
at91_softc->sc_sys_sh, IC_IECR, 1 << nb);
bus_space_write_4(at91_softc->sc_st, at91_softc->sc_sys_sh,
at91_softc->sc_aic_sh, IC_IECR, 1 << nb);
bus_space_write_4(at91_softc->sc_st, at91_softc->sc_aic_sh,
IC_EOICR, 0);
}
static void
at91_eoi(void *unused)
{
bus_space_write_4(at91_softc->sc_st, at91_softc->sc_sys_sh,
bus_space_write_4(at91_softc->sc_st, at91_softc->sc_aic_sh,
IC_EOICR, 0);
}
@ -761,6 +497,7 @@ static driver_t at91_driver = {
at91_methods,
sizeof(struct at91_softc),
};
static devclass_t at91_devclass;
DRIVER_MODULE(atmelarm, nexus, at91_driver, at91_devclass, 0, 0);

View file

@ -90,9 +90,10 @@ __FBSDID("$FreeBSD$");
#include <sys/reboot.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_rm9200.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91board.h>
#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
#define KERNEL_PT_KERN 1
@ -140,7 +141,7 @@ static void *boot_arg2;
static struct trapframe proc0_tf;
/* Static device mappings. */
static const struct pmap_devmap at91rm9200_devmap[] = {
const struct pmap_devmap at91_devmap[] = {
/*
* Map the on-board devices VA == PA so that we can access them
* with the MMU on or off.
@ -153,60 +154,88 @@ static const struct pmap_devmap at91rm9200_devmap[] = {
*/
0xdff00000,
0xfff00000,
0x100000,
0x00100000,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/*
* We can't just map the OHCI registers VA == PA, because
* AT91RM92_OHCI_BASE belongs to the userland address space.
/* We can't just map the OHCI registers VA == PA, because
* AT91xx_xxx_BASE belongs to the userland address space.
* We could just choose a different virtual address, but a better
* solution would probably be to just use pmap_mapdev() to allocate
* KVA, as we don't need the OHCI controller before the vm
* initialization is done. However, the AT91 resource allocation
* system doesn't know how to use pmap_mapdev() yet.
* Care must be taken to ensure PA and VM address do not overlap
* between entries.
*/
{
/*
* Add the ohci controller, and anything else that might be
* on this chip select for a VA/PA mapping.
*/
/* Internal Memory 1MB */
AT91RM92_OHCI_BASE,
AT91RM92_OHCI_PA_BASE,
AT91RM92_OHCI_SIZE,
0x00100000,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
{
/* CompactFlash controller. */
/* CompactFlash controller. Portion of EBI CS4 1MB */
AT91RM92_CF_BASE,
AT91RM92_CF_PA_BASE,
AT91RM92_CF_SIZE,
0x00100000,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* The next two should be good for the 9260, 9261 and 9G20 since
* addresses mapping is the same. */
{
/* Internal Memory 1MB */
AT91SAM9G20_OHCI_BASE,
AT91SAM9G20_OHCI_PA_BASE,
0x00100000,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
{
0,
0,
0,
0,
0,
}
/* EBI CS3 256MB */
AT91SAM9G20_NAND_BASE,
AT91SAM9G20_NAND_PA_BASE,
AT91SAM9G20_NAND_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
{ 0, 0, 0, 0, 0, }
};
long
at91_ramsize(void)
{
uint32_t *SDRAMC = (uint32_t *)(AT91RM92_BASE + AT91RM92_SDRAMC_BASE);
uint32_t *SDRAMC = (uint32_t *)(AT91_BASE + AT91RM92_SDRAMC_BASE);
uint32_t cr, mr;
int banks, rows, cols, bw;
cr = SDRAMC[AT91RM92_SDRAMC_CR / 4];
mr = SDRAMC[AT91RM92_SDRAMC_MR / 4];
bw = (mr & AT91RM92_SDRAMC_MR_DBW_16) ? 1 : 2;
banks = (cr & AT91RM92_SDRAMC_CR_NB_4) ? 2 : 1;
rows = ((cr & AT91RM92_SDRAMC_CR_NR_MASK) >> 2) + 11;
cols = (cr & AT91RM92_SDRAMC_CR_NC_MASK) + 8;
if (at91_is_rm92()) {
SDRAMC = (uint32_t *)(AT91_BASE + AT91RM92_SDRAMC_BASE);
cr = SDRAMC[AT91RM92_SDRAMC_CR / 4];
mr = SDRAMC[AT91RM92_SDRAMC_MR / 4];
banks = (cr & AT91RM92_SDRAMC_CR_NB_4) ? 2 : 1;
rows = ((cr & AT91RM92_SDRAMC_CR_NR_MASK) >> 2) + 11;
cols = (cr & AT91RM92_SDRAMC_CR_NC_MASK) + 8;
bw = (mr & AT91RM92_SDRAMC_MR_DBW_16) ? 1 : 2;
} else {
/* This should be good for the 9260, 9261 and 9G20 as addresses
* and registers are the same */
SDRAMC = (uint32_t *)(AT91_BASE + AT91SAM9G20_SDRAMC_BASE);
cr = SDRAMC[AT91SAM9G20_SDRAMC_CR / 4];
mr = SDRAMC[AT91SAM9G20_SDRAMC_MR / 4];
banks = (cr & AT91SAM9G20_SDRAMC_CR_NB_4) ? 2 : 1;
rows = ((cr & AT91SAM9G20_SDRAMC_CR_NR_MASK) >> 2) + 11;
cols = (cr & AT91SAM9G20_SDRAMC_CR_NC_MASK) + 8;
bw = (cr & AT91SAM9G20_SDRAMC_CR_DBW_16) ? 1 : 2;
}
return (1 << (cols + rows + banks + bw));
}
@ -326,12 +355,18 @@ initarm(void *arg, void *arg2)
VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
}
pmap_devmap_bootstrap(l1pagetable, at91rm9200_devmap);
pmap_devmap_bootstrap(l1pagetable, at91_devmap);
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
cninit();
/* Get chip id so device drivers know about differences */
at91_chip_id = *(volatile uint32_t *)
(AT91_BASE + AT91_DBGU_BASE + DBGU_C1R);
memsize = board_init();
physmem = memsize / PAGE_SIZE;

View file

@ -1,6 +1,7 @@
/*-
* Copyright (c) 2006 Bernd Walter. All rights reserved.
* Copyright (c) 2006 M. Warner Losh. All rights reserved.
* Copyright (c) 2010 Greg Ansley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -42,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/queue.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/timetc.h>
#include <sys/watchdog.h>
@ -52,16 +54,19 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_mcireg.h>
#include <arm/at91/at91_pdcreg.h>
#include <dev/mmc/bridge.h>
#include <dev/mmc/mmcreg.h>
#include <dev/mmc/mmcbrvar.h>
#include "mmcbr_if.h"
#include "opt_at91.h"
#define BBSZ 512
struct at91_mci_softc {
@ -69,8 +74,9 @@ struct at91_mci_softc {
device_t dev;
int sc_cap;
#define CAP_HAS_4WIRE 1 /* Has 4 wire bus */
#define CAP_NEEDS_BOUNCE 2 /* broken hardware needing bounce */
#define CAP_NEEDS_BYTESWAP 2 /* broken hardware needing bounce */
int flags;
int has_4wire;
#define CMD_STARTED 1
#define STOP_STARTED 2
struct resource *irq_res; /* IRQ resource */
@ -89,7 +95,7 @@ struct at91_mci_softc {
static inline uint32_t
RD4(struct at91_mci_softc *sc, bus_size_t off)
{
return bus_read_4(sc->mem_res, off);
return (bus_read_4(sc->mem_res, off));
}
static inline void
@ -140,7 +146,13 @@ at91_mci_init(device_t dev)
WR4(sc, MCI_IDR, 0xffffffff); /* Turn off interrupts */
WR4(sc, MCI_DTOR, MCI_DTOR_DTOMUL_1M | 1);
WR4(sc, MCI_MR, 0x834a); // XXX GROSS HACK FROM LINUX
#ifndef AT91_MCI_SLOT_B
WR4(sc, MCI_SDCR, 0); /* SLOT A, 1 bit bus */
#else
/* XXX Really should add second "unit" but nobody using using
* a two slot card that we know of. XXX */
WR4(sc, MCI_SDCR, 1); /* SLOT B, 1 bit bus */
#endif
}
static void
@ -165,11 +177,16 @@ static int
at91_mci_attach(device_t dev)
{
struct at91_mci_softc *sc = device_get_softc(dev);
int err;
struct sysctl_ctx_list *sctx;
struct sysctl_oid *soid;
device_t child;
int err;
sc->dev = dev;
sc->sc_cap = CAP_NEEDS_BOUNCE;
sc->sc_cap = 0;
if (at91_is_rm92())
sc->sc_cap |= CAP_NEEDS_BYTESWAP;
err = at91_mci_activate(dev);
if (err)
goto out;
@ -201,13 +218,28 @@ at91_mci_attach(device_t dev)
AT91_MCI_LOCK_DESTROY(sc);
goto out;
}
sctx = device_get_sysctl_ctx(dev);
soid = device_get_sysctl_tree(dev);
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "4wire",
CTLFLAG_RW, &sc->has_4wire, 0, "has 4 wire SD Card bus");
#ifdef AT91_MCI_HAS_4WIRE
sc->has_4wire = 1;
#endif
if (sc->has_4wire)
sc->sc_cap |= CAP_HAS_4WIRE;
sc->host.f_min = at91_master_clock / 512;
sc->host.f_min = 375000;
sc->host.f_max = at91_master_clock / 2; /* Typically 30MHz */
sc->host.f_max = at91_master_clock / 2;
if (sc->host.f_max > 50000000)
sc->host.f_max = 50000000; /* Limit to 50MHz */
sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
sc->host.caps = 0;
if (sc->sc_cap & CAP_HAS_4WIRE)
sc->host.caps = MMC_CAP_4_BIT_DATA;
else
sc->host.caps = 0;
sc->host.caps |= MMC_CAP_4_BIT_DATA;
child = device_add_child(dev, "mmc", 0);
device_set_ivars(dev, &sc->host);
err = bus_generic_attach(dev);
@ -237,11 +269,13 @@ at91_mci_activate(device_t dev)
RF_ACTIVE);
if (sc->mem_res == NULL)
goto errout;
rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (sc->irq_res == NULL)
goto errout;
return (0);
errout:
at91_mci_deactivate(dev);
@ -316,14 +350,16 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
uint32_t *src, *dst;
int i;
struct mmc_data *data;
struct mmc_request *req;
void *vaddr;
bus_addr_t paddr;
sc->curcmd = cmd;
data = cmd->data;
cmdr = cmd->opcode;
req = cmd->mrq;
/* XXX Upper layers don't always set this */
cmd->mrq = sc->req;
if (MMC_RSP(cmd->flags) == MMC_RSP_NONE)
cmdr |= MCI_CMDR_RSPTYP_NO;
else {
@ -364,26 +400,30 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
if (cmdr & MCI_CMDR_TRDIR)
vaddr = cmd->data->data;
else {
if (sc->sc_cap & CAP_NEEDS_BOUNCE) {
vaddr = sc->bounce_buffer;
src = (uint32_t *)cmd->data->data;
dst = (uint32_t *)vaddr;
/* Use bounce buffer even if we don't need
* byteswap, since buffer may straddle a page
* boundry, and we don't handle multi-segment
* transfers in hardware.
* (page issues seen from 'bsdlabel -w' which
* uses raw geom access to the volume).
* Greg Ansley (gja (at) ansley.com)
*/
vaddr = sc->bounce_buffer;
src = (uint32_t *)cmd->data->data;
dst = (uint32_t *)vaddr;
if (sc->sc_cap & CAP_NEEDS_BYTESWAP) {
for (i = 0; i < data->len / 4; i++)
dst[i] = bswap32(src[i]);
}
else
vaddr = cmd->data->data;
} else
memcpy(dst, src, data->len);
}
data->xfer_len = 0;
if (bus_dmamap_load(sc->dmatag, sc->map, vaddr, data->len,
at91_mci_getaddr, &paddr, 0) != 0) {
if (req->cmd->flags & STOP_STARTED)
req->stop->error = MMC_ERR_NO_MEMORY;
else
req->cmd->error = MMC_ERR_NO_MEMORY;
cmd->error = MMC_ERR_NO_MEMORY;
sc->req = NULL;
sc->curcmd = NULL;
req->done(req);
cmd->mrq->done(cmd->mrq);
return;
}
sc->mapped++;
@ -451,7 +491,7 @@ at91_mci_request(device_t brdev, device_t reqdev, struct mmc_request *req)
// XXX maybe the idea is naive...
if (sc->req != NULL) {
AT91_MCI_UNLOCK(sc);
return EBUSY;
return (EBUSY);
}
sc->req = req;
sc->flags = 0;
@ -503,7 +543,7 @@ at91_mci_read_done(struct at91_mci_softc *sc)
bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->dmatag, sc->map);
sc->mapped--;
if (sc->sc_cap & CAP_NEEDS_BOUNCE) {
if (sc->sc_cap & CAP_NEEDS_BYTESWAP) {
walker = (uint32_t *)cmd->data->data;
len = cmd->data->len / 4;
for (i = 0; i < len; i++)
@ -653,6 +693,13 @@ at91_mci_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
*(int *)result = sc->host.ios.vdd;
break;
case MMCBR_IVAR_CAPS:
if (sc->has_4wire) {
sc->sc_cap |= CAP_HAS_4WIRE;
sc->host.caps |= MMC_CAP_4_BIT_DATA;
} else {
sc->sc_cap &= ~CAP_HAS_4WIRE;
sc->host.caps &= ~MMC_CAP_4_BIT_DATA;
}
*(int *)result = sc->host.caps;
break;
case MMCBR_IVAR_MAX_DATA:

View file

@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/bus.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91_pioreg.h>
#include <arm/at91/at91_piovar.h>
@ -58,7 +58,7 @@ struct at91_pio_softc
static inline uint32_t
RD4(struct at91_pio_softc *sc, bus_size_t off)
{
return bus_read_4(sc->mem_res, off);
return (bus_read_4(sc->mem_res, off));
}
static inline void
@ -283,7 +283,7 @@ at91_pio_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
void
at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_ASR / 4] = periph_a_mask;
PIO[PIO_PDR / 4] = periph_a_mask;
@ -296,7 +296,7 @@ at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup)
void
at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_BSR / 4] = periph_b_mask;
PIO[PIO_PDR / 4] = periph_b_mask;
@ -309,7 +309,7 @@ at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup)
void
at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_PER / 4] = gpio_mask;
}
@ -317,7 +317,7 @@ at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask)
void
at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_ODR / 4] = input_enable_mask;
}
@ -325,7 +325,7 @@ at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask)
void
at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_OER / 4] = output_enable_mask;
if (use_pullup)
@ -337,7 +337,7 @@ at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup)
void
at91_pio_gpio_set(uint32_t pio, uint32_t data_mask)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_SODR / 4] = data_mask;
}
@ -345,7 +345,7 @@ at91_pio_gpio_set(uint32_t pio, uint32_t data_mask)
void
at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
PIO[PIO_CODR / 4] = data_mask;
}
@ -353,7 +353,7 @@ at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask)
uint8_t
at91_pio_gpio_get(uint32_t pio, uint32_t data_mask)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
data_mask &= PIO[PIO_PDSR / 4];
@ -363,7 +363,7 @@ at91_pio_gpio_get(uint32_t pio, uint32_t data_mask)
void
at91_pio_gpio_set_deglitch(uint32_t pio, uint32_t data_mask, int use_deglitch)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
if (use_deglitch)
PIO[PIO_IFER / 4] = data_mask;
@ -376,7 +376,7 @@ void
at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask,
int enable_interrupt)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
if (enable_interrupt)
PIO[PIO_IER / 4] = data_mask;
@ -388,7 +388,7 @@ at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask,
uint32_t
at91_pio_gpio_clear_interrupt(uint32_t pio)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
/* reading this register will clear the interrupts */
return (PIO[PIO_ISR / 4]);
}

View file

@ -1,5 +1,9 @@
/* $FreeBSD$ */
#ifndef ARM_AT91_AT91_PIO_RM9200_H
#define ARM_AT91_AT91_PIO_RM9200_H
#include <arm/at91/at91_pioreg.h>
/*
* These defines come from an atmel file that says specifically that it
* has no copyright.
@ -8,317 +12,197 @@
//*****************************************************************************
// PIO DEFINITIONS FOR AT91RM9200
//*****************************************************************************
#define AT91C_PIO_PA0 (1u << 0) // Pin Controlled by PA0
#define AT91C_PA0_MISO (AT91C_PIO_PA0) // SPI Master In Slave
#define AT91C_PA0_PCK3 (AT91C_PIO_PA0) // PMC Programmable Clock Output 3
#define AT91C_PIO_PA1 (1u << 1) // Pin Controlled by PA1
#define AT91C_PA1_MOSI (AT91C_PIO_PA1) // SPI Master Out Slave
#define AT91C_PA1_PCK0 (AT91C_PIO_PA1) // PMC Programmable Clock Output 0
#define AT91C_PIO_PA10 (1u << 10) // Pin Controlled by PA10
#define AT91C_PA10_ETX1 (AT91C_PIO_PA10) // Ethernet MAC Transmit Data 1
#define AT91C_PA10_MCDB1 (AT91C_PIO_PA10) // Multimedia Card B Data 1
#define AT91C_PIO_PA11 (1u << 11) // Pin Controlled by PA11
#define AT91C_PA11_ECRS_ECRSDV (AT91C_PIO_PA11) // Ethernet MAC Carrier Sense/Carrier Sense and Data Valid
#define AT91C_PA11_MCDB2 (AT91C_PIO_PA11) // Multimedia Card B Data 2
#define AT91C_PIO_PA12 (1u << 12) // Pin Controlled by PA12
#define AT91C_PA12_ERX0 (AT91C_PIO_PA12) // Ethernet MAC Receive Data 0
#define AT91C_PA12_MCDB3 (AT91C_PIO_PA12) // Multimedia Card B Data 3
#define AT91C_PIO_PA13 (1u << 13) // Pin Controlled by PA13
#define AT91C_PA13_ERX1 (AT91C_PIO_PA13) // Ethernet MAC Receive Data 1
#define AT91C_PA13_TCLK0 (AT91C_PIO_PA13) // Timer Counter 0 external clock input
#define AT91C_PIO_PA14 (1u << 14) // Pin Controlled by PA14
#define AT91C_PA14_ERXER (AT91C_PIO_PA14) // Ethernet MAC Receive Error
#define AT91C_PA14_TCLK1 (AT91C_PIO_PA14) // Timer Counter 1 external clock input
#define AT91C_PIO_PA15 (1u << 15) // Pin Controlled by PA15
#define AT91C_PA15_EMDC (AT91C_PIO_PA15) // Ethernet MAC Management Data Clock
#define AT91C_PA15_TCLK2 (AT91C_PIO_PA15) // Timer Counter 2 external clock input
#define AT91C_PIO_PA16 (1u << 16) // Pin Controlled by PA16
#define AT91C_PA16_EMDIO (AT91C_PIO_PA16) // Ethernet MAC Management Data Input/Output
#define AT91C_PA16_IRQ6 (AT91C_PIO_PA16) // AIC Interrupt input 6
#define AT91C_PIO_PA17 (1u << 17) // Pin Controlled by PA17
#define AT91C_PA17_TXD0 (AT91C_PIO_PA17) // USART 0 Transmit Data
#define AT91C_PA17_TIOA0 (AT91C_PIO_PA17) // Timer Counter 0 Multipurpose Timer I/O Pin A
#define AT91C_PIO_PA18 (1u << 18) // Pin Controlled by PA18
#define AT91C_PA18_RXD0 (AT91C_PIO_PA18) // USART 0 Receive Data
#define AT91C_PA18_TIOB0 (AT91C_PIO_PA18) // Timer Counter 0 Multipurpose Timer I/O Pin B
#define AT91C_PIO_PA19 (1u << 19) // Pin Controlled by PA19
#define AT91C_PA19_SCK0 (AT91C_PIO_PA19) // USART 0 Serial Clock
#define AT91C_PA19_TIOA1 (AT91C_PIO_PA19) // Timer Counter 1 Multipurpose Timer I/O Pin A
#define AT91C_PIO_PA2 (1u << 2) // Pin Controlled by PA2
#define AT91C_PA2_SPCK (AT91C_PIO_PA2) // SPI Serial Clock
#define AT91C_PA2_IRQ4 (AT91C_PIO_PA2) // AIC Interrupt Input 4
#define AT91C_PIO_PA20 (1u << 20) // Pin Controlled by PA20
#define AT91C_PA20_CTS0 (AT91C_PIO_PA20) // USART 0 Clear To Send
#define AT91C_PA20_TIOB1 (AT91C_PIO_PA20) // Timer Counter 1 Multipurpose Timer I/O Pin B
#define AT91C_PIO_PA21 (1u << 21) // Pin Controlled by PA21
#define AT91C_PA21_RTS0 (AT91C_PIO_PA21) // Usart 0 Ready To Send
#define AT91C_PA21_TIOA2 (AT91C_PIO_PA21) // Timer Counter 2 Multipurpose Timer I/O Pin A
#define AT91C_PIO_PA22 (1u << 22) // Pin Controlled by PA22
#define AT91C_PA22_RXD2 (AT91C_PIO_PA22) // USART 2 Receive Data
#define AT91C_PA22_TIOB2 (AT91C_PIO_PA22) // Timer Counter 2 Multipurpose Timer I/O Pin B
#define AT91C_PIO_PA23 (1u << 23) // Pin Controlled by PA23
#define AT91C_PA23_TXD2 (AT91C_PIO_PA23) // USART 2 Transmit Data
#define AT91C_PA23_IRQ3 (AT91C_PIO_PA23) // Interrupt input 3
#define AT91C_PIO_PA24 (1u << 24) // Pin Controlled by PA24
#define AT91C_PA24_SCK2 (AT91C_PIO_PA24) // USART2 Serial Clock
#define AT91C_PA24_PCK1 (AT91C_PIO_PA24) // PMC Programmable Clock Output 1
#define AT91C_PIO_PA25 (1u << 25) // Pin Controlled by PA25
#define AT91C_PA25_TWD (AT91C_PIO_PA25) // TWI Two-wire Serial Data
#define AT91C_PA25_IRQ2 (AT91C_PIO_PA25) // Interrupt input 2
#define AT91C_PIO_PA26 (1u << 26) // Pin Controlled by PA26
#define AT91C_PA26_TWCK (AT91C_PIO_PA26) // TWI Two-wire Serial Clock
#define AT91C_PA26_IRQ1 (AT91C_PIO_PA26) // Interrupt input 1
#define AT91C_PIO_PA27 (1u << 27) // Pin Controlled by PA27
#define AT91C_PA27_MCCK (AT91C_PIO_PA27) // Multimedia Card Clock
#define AT91C_PA27_TCLK3 (AT91C_PIO_PA27) // Timer Counter 3 External Clock Input
#define AT91C_PIO_PA28 (1u << 28) // Pin Controlled by PA28
#define AT91C_PA28_MCCDA (AT91C_PIO_PA28) // Multimedia Card A Command
#define AT91C_PA28_TCLK4 (AT91C_PIO_PA28) // Timer Counter 4 external Clock Input
#define AT91C_PIO_PA29 (1u << 29) // Pin Controlled by PA29
#define AT91C_PA29_MCDA0 (AT91C_PIO_PA29) // Multimedia Card A Data 0
#define AT91C_PA29_TCLK5 (AT91C_PIO_PA29) // Timer Counter 5 external clock input
#define AT91C_PIO_PA3 (1u << 3) // Pin Controlled by PA3
#define AT91C_PA3_NPCS0 (AT91C_PIO_PA3) // SPI Peripheral Chip Select 0
#define AT91C_PA3_IRQ5 (AT91C_PIO_PA3) // AIC Interrupt Input 5
#define AT91C_PIO_PA30 (1u << 30) // Pin Controlled by PA30
#define AT91C_PA30_DRXD (AT91C_PIO_PA30) // DBGU Debug Receive Data
#define AT91C_PA30_CTS2 (AT91C_PIO_PA30) // Usart 2 Clear To Send
#define AT91C_PIO_PA31 (1u << 31) // Pin Controlled by PA31
#define AT91C_PA31_DTXD (AT91C_PIO_PA31) // DBGU Debug Transmit Data
#define AT91C_PA31_RTS2 (AT91C_PIO_PA31) // USART 2 Ready To Send
#define AT91C_PIO_PA4 (1u << 4) // Pin Controlled by PA4
#define AT91C_PA4_NPCS1 (AT91C_PIO_PA4) // SPI Peripheral Chip Select 1
#define AT91C_PA4_PCK1 (AT91C_PIO_PA4) // PMC Programmable Clock Output 1
#define AT91C_PIO_PA5 (1u << 5) // Pin Controlled by PA5
#define AT91C_PA5_NPCS2 (AT91C_PIO_PA5) // SPI Peripheral Chip Select 2
#define AT91C_PA5_TXD3 (AT91C_PIO_PA5) // USART 3 Transmit Data
#define AT91C_PIO_PA6 (1u << 6) // Pin Controlled by PA6
#define AT91C_PA6_NPCS3 (AT91C_PIO_PA6) // SPI Peripheral Chip Select 3
#define AT91C_PA6_RXD3 (AT91C_PIO_PA6) // USART 3 Receive Data
#define AT91C_PIO_PA7 (1u << 7) // Pin Controlled by PA7
#define AT91C_PA7_ETXCK_EREFCK (AT91C_PIO_PA7) // Ethernet MAC Transmit Clock/Reference Clock
#define AT91C_PA7_PCK2 (AT91C_PIO_PA7) // PMC Programmable Clock 2
#define AT91C_PIO_PA8 (1u << 8) // Pin Controlled by PA8
#define AT91C_PA8_ETXEN (AT91C_PIO_PA8) // Ethernet MAC Transmit Enable
#define AT91C_PA8_MCCDB (AT91C_PIO_PA8) // Multimedia Card B Command
#define AT91C_PIO_PA9 (1u << 9) // Pin Controlled by PA9
#define AT91C_PA9_ETX0 (AT91C_PIO_PA9) // Ethernet MAC Transmit Data 0
#define AT91C_PA9_MCDB0 (AT91C_PIO_PA9) // Multimedia Card B Data 0
#define AT91C_PIO_PB0 (1u << 0) // Pin Controlled by PB0
#define AT91C_PB0_TF0 (AT91C_PIO_PB0) // SSC Transmit Frame Sync 0
#define AT91C_PB0_TIOB3 (AT91C_PIO_PB0) // Timer Counter 3 Multipurpose Timer I/O Pin B
#define AT91C_PIO_PB1 (1u << 1) // Pin Controlled by PB1
#define AT91C_PB1_TK0 (AT91C_PIO_PB1) // SSC Transmit Clock 0
#define AT91C_PB1_CTS3 (AT91C_PIO_PB1) // USART 3 Clear To Send
#define AT91C_PIO_PB10 (1u << 10) // Pin Controlled by PB10
#define AT91C_PB10_RK1 (AT91C_PIO_PB10) // SSC Receive Clock 1
#define AT91C_PB10_TIOA5 (AT91C_PIO_PB10) // Timer Counter 5 Multipurpose Timer I/O Pin A
#define AT91C_PIO_PB11 (1u << 11) // Pin Controlled by PB11
#define AT91C_PB11_RF1 (AT91C_PIO_PB11) // SSC Receive Frame Sync 1
#define AT91C_PB11_TIOB5 (AT91C_PIO_PB11) // Timer Counter 5 Multipurpose Timer I/O Pin B
#define AT91C_PIO_PB12 (1u << 12) // Pin Controlled by PB12
#define AT91C_PB12_TF2 (AT91C_PIO_PB12) // SSC Transmit Frame Sync 2
#define AT91C_PB12_ETX2 (AT91C_PIO_PB12) // Ethernet MAC Transmit Data 2
#define AT91C_PIO_PB13 (1u << 13) // Pin Controlled by PB13
#define AT91C_PB13_TK2 (AT91C_PIO_PB13) // SSC Transmit Clock 2
#define AT91C_PB13_ETX3 (AT91C_PIO_PB13) // Ethernet MAC Transmit Data 3
#define AT91C_PIO_PB14 (1u << 14) // Pin Controlled by PB14
#define AT91C_PB14_TD2 (AT91C_PIO_PB14) // SSC Transmit Data 2
#define AT91C_PB14_ETXER (AT91C_PIO_PB14) // Ethernet MAC Transmikt Coding Error
#define AT91C_PIO_PB15 (1u << 15) // Pin Controlled by PB15
#define AT91C_PB15_RD2 (AT91C_PIO_PB15) // SSC Receive Data 2
#define AT91C_PB15_ERX2 (AT91C_PIO_PB15) // Ethernet MAC Receive Data 2
#define AT91C_PIO_PB16 (1u << 16) // Pin Controlled by PB16
#define AT91C_PB16_RK2 (AT91C_PIO_PB16) // SSC Receive Clock 2
#define AT91C_PB16_ERX3 (AT91C_PIO_PB16) // Ethernet MAC Receive Data 3
#define AT91C_PIO_PB17 (1u << 17) // Pin Controlled by PB17
#define AT91C_PB17_RF2 (AT91C_PIO_PB17) // SSC Receive Frame Sync 2
#define AT91C_PB17_ERXDV (AT91C_PIO_PB17) // Ethernet MAC Receive Data Valid
#define AT91C_PIO_PB18 (1u << 18) // Pin Controlled by PB18
#define AT91C_PB18_RI1 (AT91C_PIO_PB18) // USART 1 Ring Indicator
#define AT91C_PB18_ECOL (AT91C_PIO_PB18) // Ethernet MAC Collision Detected
#define AT91C_PIO_PB19 (1u << 19) // Pin Controlled by PB19
#define AT91C_PB19_DTR1 (AT91C_PIO_PB19) // USART 1 Data Terminal ready
#define AT91C_PB19_ERXCK (AT91C_PIO_PB19) // Ethernet MAC Receive Clock
#define AT91C_PIO_PB2 (1u << 2) // Pin Controlled by PB2
#define AT91C_PB2_TD0 (AT91C_PIO_PB2) // SSC Transmit data
#define AT91C_PB2_SCK3 (AT91C_PIO_PB2) // USART 3 Serial Clock
#define AT91C_PIO_PB20 (1u << 20) // Pin Controlled by PB20
#define AT91C_PB20_TXD1 (AT91C_PIO_PB20) // USART 1 Transmit Data
#define AT91C_PIO_PB21 (1u << 21) // Pin Controlled by PB21
#define AT91C_PB21_RXD1 (AT91C_PIO_PB21) // USART 1 Receive Data
#define AT91C_PIO_PB22 (1u << 22) // Pin Controlled by PB22
#define AT91C_PB22_SCK1 (AT91C_PIO_PB22) // USART1 Serial Clock
#define AT91C_PIO_PB23 (1u << 23) // Pin Controlled by PB23
#define AT91C_PB23_DCD1 (AT91C_PIO_PB23) // USART 1 Data Carrier Detect
#define AT91C_PIO_PB24 (1u << 24) // Pin Controlled by PB24
#define AT91C_PB24_CTS1 (AT91C_PIO_PB24) // USART 1 Clear To Send
#define AT91C_PIO_PB25 (1u << 25) // Pin Controlled by PB25
#define AT91C_PB25_DSR1 (AT91C_PIO_PB25) // USART 1 Data Set ready
#define AT91C_PB25_EF100 (AT91C_PIO_PB25) // Ethernet MAC Force 100 Mbits/sec
#define AT91C_PIO_PB26 (1u << 26) // Pin Controlled by PB26
#define AT91C_PB26_RTS1 (AT91C_PIO_PB26) // Usart 0 Ready To Send
#define AT91C_PIO_PB27 (1u << 27) // Pin Controlled by PB27
#define AT91C_PB27_PCK0 (AT91C_PIO_PB27) // PMC Programmable Clock Output 0
#define AT91C_PIO_PB28 (1u << 28) // Pin Controlled by PB28
#define AT91C_PB28_FIQ (AT91C_PIO_PB28) // AIC Fast Interrupt Input
#define AT91C_PIO_PB29 (1u << 29) // Pin Controlled by PB29
#define AT91C_PB29_IRQ0 (AT91C_PIO_PB29) // Interrupt input 0
#define AT91C_PIO_PB3 (1u << 3) // Pin Controlled by PB3
#define AT91C_PB3_RD0 (AT91C_PIO_PB3) // SSC Receive Data
#define AT91C_PB3_MCDA1 (AT91C_PIO_PB3) // Multimedia Card A Data 1
#define AT91C_PIO_PB4 (1u << 4) // Pin Controlled by PB4
#define AT91C_PB4_RK0 (AT91C_PIO_PB4) // SSC Receive Clock
#define AT91C_PB4_MCDA2 (AT91C_PIO_PB4) // Multimedia Card A Data 2
#define AT91C_PIO_PB5 (1u << 5) // Pin Controlled by PB5
#define AT91C_PB5_RF0 (AT91C_PIO_PB5) // SSC Receive Frame Sync 0
#define AT91C_PB5_MCDA3 (AT91C_PIO_PB5) // Multimedia Card A Data 3
#define AT91C_PIO_PB6 (1u << 6) // Pin Controlled by PB6
#define AT91C_PB6_TF1 (AT91C_PIO_PB6) // SSC Transmit Frame Sync 1
#define AT91C_PB6_TIOA3 (AT91C_PIO_PB6) // Timer Counter 4 Multipurpose Timer I/O Pin A
#define AT91C_PIO_PB7 (1u << 7) // Pin Controlled by PB7
#define AT91C_PB7_TK1 (AT91C_PIO_PB7) // SSC Transmit Clock 1
#define AT91C_PB7_TIOB3 (AT91C_PIO_PB7) // Timer Counter 3 Multipurpose Timer I/O Pin B
#define AT91C_PIO_PB8 (1u << 8) // Pin Controlled by PB8
#define AT91C_PB8_TD1 (AT91C_PIO_PB8) // SSC Transmit Data 1
#define AT91C_PB8_TIOA4 (AT91C_PIO_PB8) // Timer Counter 4 Multipurpose Timer I/O Pin A
#define AT91C_PIO_PB9 (1u << 9) // Pin Controlled by PB9
#define AT91C_PB9_RD1 (AT91C_PIO_PB9) // SSC Receive Data 1
#define AT91C_PB9_TIOB4 (AT91C_PIO_PB9) // Timer Counter 4 Multipurpose Timer I/O Pin B
#define AT91C_PIO_PC0 (1u << 0) // Pin Controlled by PC0
#define AT91C_PC0_BFCK (AT91C_PIO_PC0) // Burst Flash Clock
#define AT91C_PIO_PC1 (1u << 1) // Pin Controlled by PC1
#define AT91C_PC1_BFRDY_SMOE (AT91C_PIO_PC1) // Burst Flash Ready
#define AT91C_PIO_PC10 (1u << 10) // Pin Controlled by PC10
#define AT91C_PC10_NCS4_CFCS (AT91C_PIO_PC10) // Compact Flash Chip Select
#define AT91C_PIO_PC11 (1u << 11) // Pin Controlled by PC11
#define AT91C_PC11_NCS5_CFCE1 (AT91C_PIO_PC11) // Chip Select 5 / Compact Flash Chip Enable 1
#define AT91C_PIO_PC12 (1u << 12) // Pin Controlled by PC12
#define AT91C_PC12_NCS6_CFCE2 (AT91C_PIO_PC12) // Chip Select 6 / Compact Flash Chip Enable 2
#define AT91C_PIO_PC13 (1u << 13) // Pin Controlled by PC13
#define AT91C_PC13_NCS7 (AT91C_PIO_PC13) // Chip Select 7
#define AT91C_PIO_PC14 (1u << 14) // Pin Controlled by PC14
#define AT91C_PIO_PC15 (1u << 15) // Pin Controlled by PC15
#define AT91C_PIO_PC16 (1u << 16) // Pin Controlled by PC16
#define AT91C_PC16_D16 (AT91C_PIO_PC16) // Data Bus [16]
#define AT91C_PIO_PC17 (1u << 17) // Pin Controlled by PC17
#define AT91C_PC17_D17 (AT91C_PIO_PC17) // Data Bus [17]
#define AT91C_PIO_PC18 (1u << 18) // Pin Controlled by PC18
#define AT91C_PC18_D18 (AT91C_PIO_PC18) // Data Bus [18]
#define AT91C_PIO_PC19 (1u << 19) // Pin Controlled by PC19
#define AT91C_PC19_D19 (AT91C_PIO_PC19) // Data Bus [19]
#define AT91C_PIO_PC2 (1u << 2) // Pin Controlled by PC2
#define AT91C_PC2_BFAVD (AT91C_PIO_PC2)u // Burst Flash Address Valid
#define AT91C_PIO_PC20 (1u << 20) // Pin Controlled by PC20
#define AT91C_PC20_D20 (AT91C_PIO_PC20) // Data Bus [20]
#define AT91C_PIO_PC21 (1u << 21) // Pin Controlled by PC21
#define AT91C_PC21_D21 (AT91C_PIO_PC21) // Data Bus [21]
#define AT91C_PIO_PC22 (1u << 22) // Pin Controlled by PC22
#define AT91C_PC22_D22 (AT91C_PIO_PC22) // Data Bus [22]
#define AT91C_PIO_PC23 (1u << 23) // Pin Controlled by PC23
#define AT91C_PC23_D23 (AT91C_PIO_PC23) // Data Bus [23]
#define AT91C_PIO_PC24 (1u << 24) // Pin Controlled by PC24
#define AT91C_PC24_D24 (AT91C_PIO_PC24) // Data Bus [24]
#define AT91C_PIO_PC25 (1u << 25) // Pin Controlled by PC25
#define AT91C_PC25_D25 (AT91C_PIO_PC25) // Data Bus [25]
#define AT91C_PIO_PC26 (1u << 26) // Pin Controlled by PC26
#define AT91C_PC26_D26 (AT91C_PIO_PC26) // Data Bus [26]
#define AT91C_PIO_PC27 (1u << 27) // Pin Controlled by PC27
#define AT91C_PC27_D27 (AT91C_PIO_PC27) // Data Bus [27]
#define AT91C_PIO_PC28 (1u << 28) // Pin Controlled by PC28
#define AT91C_PC28_D28 (AT91C_PIO_PC28) // Data Bus [28]
#define AT91C_PIO_PC29 (1u << 29) // Pin Controlled by PC29
#define AT91C_PC29_D29 (AT91C_PIO_PC29) // Data Bus [29]
#define AT91C_PIO_PC3 (1u << 3) // Pin Controlled by PC3
#define AT91C_PC3_BFBAA_SMWE (AT91C_PIO_PC3) // Burst Flash Address Advance / SmartMedia Write Enable
#define AT91C_PIO_PC30 (1u << 30) // Pin Controlled by PC30
#define AT91C_PC30_D30 (AT91C_PIO_PC30) // Data Bus [30]
#define AT91C_PIO_PC31 (1u << 31) // Pin Controlled by PC31
#define AT91C_PC31_D31 (AT91C_PIO_PC31) // Data Bus [31]
#define AT91C_PIO_PC4 (1u << 4) // Pin Controlled by PC4
#define AT91C_PC4_BFOE (AT91C_PIO_PC4) // Burst Flash Output Enable
#define AT91C_PIO_PC5 (1u << 5) // Pin Controlled by PC5
#define AT91C_PC5_BFWE (AT91C_PIO_PC5) // Burst Flash Write Enable
#define AT91C_PIO_PC6 (1u << 6) // Pin Controlled by PC6
#define AT91C_PC6_NWAIT (AT91C_PIO_PC6) // NWAIT
#define AT91C_PIO_PC7 (1u << 7) // Pin Controlled by PC7
#define AT91C_PC7_A23 (AT91C_PIO_PC7) // Address Bus[23]
#define AT91C_PIO_PC8 (1u << 8) // Pin Controlled by PC8
#define AT91C_PC8_A24 (AT91C_PIO_PC8) // Address Bus[24]
#define AT91C_PIO_PC9 (1u << 9) // Pin Controlled by PC9
#define AT91C_PC9_A25_CFRNW (AT91C_PIO_PC9) // Address Bus[25] / Compact Flash Read Not Write
#define AT91C_PIO_PD0 (1u << 0) // Pin Controlled by PD0
#define AT91C_PD0_ETX0 (AT91C_PIO_PD0) // Ethernet MAC Transmit Data 0
#define AT91C_PIO_PD1 (1u << 1) // Pin Controlled by PD1
#define AT91C_PD1_ETX1 (AT91C_PIO_PD1) // Ethernet MAC Transmit Data 1
#define AT91C_PIO_PD10 (1u << 10) // Pin Controlled by PD10
#define AT91C_PD10_PCK3 (AT91C_PIO_PD10) // PMC Programmable Clock Output 3
#define AT91C_PD10_TPS1 (AT91C_PIO_PD10) // ETM ARM9 pipeline status 1
#define AT91C_PIO_PD11 (1u << 11) // Pin Controlled by PD11
#define AT91C_PD11_ (AT91C_PIO_PD11) //
#define AT91C_PD11_TPS2 (AT91C_PIO_PD11) // ETM ARM9 pipeline status 2
#define AT91C_PIO_PD12 (1u << 12) // Pin Controlled by PD12
#define AT91C_PD12_ (AT91C_PIO_PD12) //
#define AT91C_PD12_TPK0 (AT91C_PIO_PD12) // ETM Trace Packet 0
#define AT91C_PIO_PD13 (1u << 13) // Pin Controlled by PD13
#define AT91C_PD13_ (AT91C_PIO_PD13) //
#define AT91C_PD13_TPK1 (AT91C_PIO_PD13) // ETM Trace Packet 1
#define AT91C_PIO_PD14 (1u << 14) // Pin Controlled by PD14
#define AT91C_PD14_ (AT91C_PIO_PD14) //
#define AT91C_PD14_TPK2 (AT91C_PIO_PD14) // ETM Trace Packet 2
#define AT91C_PIO_PD15 (1u << 15) // Pin Controlled by PD15
#define AT91C_PD15_TD0 (AT91C_PIO_PD15) // SSC Transmit data
#define AT91C_PD15_TPK3 (AT91C_PIO_PD15) // ETM Trace Packet 3
#define AT91C_PIO_PD16 (1u << 16) // Pin Controlled by PD16
#define AT91C_PD16_TD1 (AT91C_PIO_PD16) // SSC Transmit Data 1
#define AT91C_PD16_TPK4 (AT91C_PIO_PD16) // ETM Trace Packet 4
#define AT91C_PIO_PD17 (1u << 17) // Pin Controlled by PD17
#define AT91C_PD17_TD2 (AT91C_PIO_PD17) // SSC Transmit Data 2
#define AT91C_PD17_TPK5 (AT91C_PIO_PD17) // ETM Trace Packet 5
#define AT91C_PIO_PD18 (1u << 18) // Pin Controlled by PD18
#define AT91C_PD18_NPCS1 (AT91C_PIO_PD18) // SPI Peripheral Chip Select 1
#define AT91C_PD18_TPK6 (AT91C_PIO_PD18) // ETM Trace Packet 6
#define AT91C_PIO_PD19 (1u << 19) // Pin Controlled by PD19
#define AT91C_PD19_NPCS2 (AT91C_PIO_PD19) // SPI Peripheral Chip Select 2
#define AT91C_PD19_TPK7 (AT91C_PIO_PD19) // ETM Trace Packet 7
#define AT91C_PIO_PD2 (1u << 2) // Pin Controlled by PD2
#define AT91C_PD2_ETX2 (AT91C_PIO_PD2) // Ethernet MAC Transmit Data 2
#define AT91C_PIO_PD20 (1u << 20) // Pin Controlled by PD20
#define AT91C_PD20_NPCS3 (AT91C_PIO_PD20) // SPI Peripheral Chip Select 3
#define AT91C_PD20_TPK8 (AT91C_PIO_PD20) // ETM Trace Packet 8
#define AT91C_PIO_PD21 (1u << 21) // Pin Controlled by PD21
#define AT91C_PD21_RTS0 (AT91C_PIO_PD21) // Usart 0 Ready To Send
#define AT91C_PD21_TPK9 (AT91C_PIO_PD21) // ETM Trace Packet 9
#define AT91C_PIO_PD22 (1u << 22) // Pin Controlled by PD22
#define AT91C_PD22_RTS1 (AT91C_PIO_PD22) // Usart 0 Ready To Send
#define AT91C_PD22_TPK10 (AT91C_PIO_PD22) // ETM Trace Packet 10
#define AT91C_PIO_PD23 (1u << 23) // Pin Controlled by PD23
#define AT91C_PD23_RTS2 (AT91C_PIO_PD23) // USART 2 Ready To Send
#define AT91C_PD23_TPK11 (AT91C_PIO_PD23) // ETM Trace Packet 11
#define AT91C_PIO_PD24 (1u << 24) // Pin Controlled by PD24
#define AT91C_PD24_RTS3 (AT91C_PIO_PD24) // USART 3 Ready To Send
#define AT91C_PD24_TPK12 (AT91C_PIO_PD24) // ETM Trace Packet 12
#define AT91C_PIO_PD25 (1u << 25) // Pin Controlled by PD25
#define AT91C_PD25_DTR1 (AT91C_PIO_PD25) // USART 1 Data Terminal ready
#define AT91C_PD25_TPK13 (AT91C_PIO_PD25) // ETM Trace Packet 13
#define AT91C_PIO_PD26 (1u << 26) // Pin Controlled by PD26
#define AT91C_PD26_TPK14 (AT91C_PIO_PD26) // ETM Trace Packet 14
#define AT91C_PIO_PD27 (1u << 27) // Pin Controlled by PD27
#define AT91C_PD27_TPK15 (AT91C_PIO_PD27) // ETM Trace Packet 15
#define AT91C_PIO_PD3 (1u << 3) // Pin Controlled by PD3
#define AT91C_PD3_ETX3 (AT91C_PIO_PD3) // Ethernet MAC Transmit Data 3
#define AT91C_PIO_PD4 (1u << 4) // Pin Controlled by PD4
#define AT91C_PD4_ETXEN (AT91C_PIO_PD4) // Ethernet MAC Transmit Enable
#define AT91C_PIO_PD5 (1u << 5) // Pin Controlled by PD5
#define AT91C_PD5_ETXER (AT91C_PIO_PD5) // Ethernet MAC Transmikt Coding Error
#define AT91C_PIO_PD6 (1u << 6) // Pin Controlled by PD6
#define AT91C_PD6_DTXD (AT91C_PIO_PD6) // DBGU Debug Transmit Data
#define AT91C_PIO_PD7 (1u << 7) // Pin Controlled by PD7
#define AT91C_PD7_PCK0 (AT91C_PIO_PD7) // PMC Programmable Clock Output 0
#define AT91C_PD7_TSYNC (AT91C_PIO_PD7) // ETM Synchronization signal
#define AT91C_PIO_PD8 (1u << 8) // Pin Controlled by PD8
#define AT91C_PD8_PCK1 (AT91C_PIO_PD8) // PMC Programmable Clock Output 1
#define AT91C_PD8_TCLK (AT91C_PIO_PD8) // ETM Trace Clock signal
#define AT91C_PIO_PD9 (1u << 9) // Pin Controlled by PD9
#define AT91C_PD9_PCK2 (AT91C_PIO_PD9) // PMC Programmable Clock 2
#define AT91C_PD9_TPS0 (AT91C_PIO_PD9) // ETM ARM9 pipeline status 0
#endif /* ARM_AT91_AT91_PIO_RM9200_H */

View file

@ -1,291 +0,0 @@
/*
* Theses defines come from an atmel file that says specifically that it
* has no copyright.
*/
/* $FreeBSD$ */
// *****************************************************************************
// PIO DEFINITIONS FOR AT91SAM9261
// *****************************************************************************
#define AT91C_PIO_PA0 ((unsigned int) 1 << 0) // Pin Controlled by PA0
#define AT91C_PA0_MISO0 ((unsigned int) AT91C_PIO_PA0) // SPI0 Master In Slave
#define AT91C_PA0_MCDA0 ((unsigned int) AT91C_PIO_PA0) // Multimedia Card A Data 0
#define AT91C_PIO_PA1 ((unsigned int) 1 << 1) // Pin Controlled by PA1
#define AT91C_PA1_MOSI0 ((unsigned int) AT91C_PIO_PA1) // SPI0 Master Out Slave
#define AT91C_PA1_MCCDA ((unsigned int) AT91C_PIO_PA1) // Multimedia Card A Command
#define AT91C_PIO_PA10 ((unsigned int) 1 << 10) // Pin Controlled by PA10
#define AT91C_PA10_DTXD ((unsigned int) AT91C_PIO_PA10) // DBGU Debug Transmit Data
#define AT91C_PA10_PCK3 ((unsigned int) AT91C_PIO_PA10) // PMC Programmable clock Output 3
#define AT91C_PIO_PA11 ((unsigned int) 1 << 11) // Pin Controlled by PA11
#define AT91C_PA11_TSYNC ((unsigned int) AT91C_PIO_PA11) // Trace Synchronization Signal
#define AT91C_PA11_SCK1 ((unsigned int) AT91C_PIO_PA11) // USART1 Serial Clock
#define AT91C_PIO_PA12 ((unsigned int) 1 << 12) // Pin Controlled by PA12
#define AT91C_PA12_TCLK ((unsigned int) AT91C_PIO_PA12) // Trace Clock
#define AT91C_PA12_RTS1 ((unsigned int) AT91C_PIO_PA12) // USART1 Ready To Send
#define AT91C_PIO_PA13 ((unsigned int) 1 << 13) // Pin Controlled by PA13
#define AT91C_PA13_TPS0 ((unsigned int) AT91C_PIO_PA13) // Trace ARM Pipeline Status 0
#define AT91C_PA13_CTS1 ((unsigned int) AT91C_PIO_PA13) // USART1 Clear To Send
#define AT91C_PIO_PA14 ((unsigned int) 1 << 14) // Pin Controlled by PA14
#define AT91C_PA14_TPS1 ((unsigned int) AT91C_PIO_PA14) // Trace ARM Pipeline Status 1
#define AT91C_PA14_SCK2 ((unsigned int) AT91C_PIO_PA14) // USART2 Serial Clock
#define AT91C_PIO_PA15 ((unsigned int) 1 << 15) // Pin Controlled by PA15
#define AT91C_PA15_TPS2 ((unsigned int) AT91C_PIO_PA15) // Trace ARM Pipeline Status 2
#define AT91C_PA15_RTS2 ((unsigned int) AT91C_PIO_PA15) // USART2 Ready To Send
#define AT91C_PIO_PA16 ((unsigned int) 1 << 16) // Pin Controlled by PA16
#define AT91C_PA16_TPK0 ((unsigned int) AT91C_PIO_PA16) // Trace Packet Port 0
#define AT91C_PA16_CTS2 ((unsigned int) AT91C_PIO_PA16) // USART2 Clear To Send
#define AT91C_PIO_PA17 ((unsigned int) 1 << 17) // Pin Controlled by PA17
#define AT91C_PA17_TPK1 ((unsigned int) AT91C_PIO_PA17) // Trace Packet Port 1
#define AT91C_PA17_TF1 ((unsigned int) AT91C_PIO_PA17) // SSC1 Transmit Frame Sync
#define AT91C_PIO_PA18 ((unsigned int) 1 << 18) // Pin Controlled by PA18
#define AT91C_PA18_TPK2 ((unsigned int) AT91C_PIO_PA18) // Trace Packet Port 2
#define AT91C_PA18_TK1 ((unsigned int) AT91C_PIO_PA18) // SSC1 Transmit Clock
#define AT91C_PIO_PA19 ((unsigned int) 1 << 19) // Pin Controlled by PA19
#define AT91C_PA19_TPK3 ((unsigned int) AT91C_PIO_PA19) // Trace Packet Port 3
#define AT91C_PA19_TD1 ((unsigned int) AT91C_PIO_PA19) // SSC1 Transmit Data
#define AT91C_PIO_PA2 ((unsigned int) 1 << 2) // Pin Controlled by PA2
#define AT91C_PA2_SPCK0 ((unsigned int) AT91C_PIO_PA2) // SPI0 Serial Clock
#define AT91C_PA2_MCCK ((unsigned int) AT91C_PIO_PA2) // Multimedia Card Clock
#define AT91C_PIO_PA20 ((unsigned int) 1 << 20) // Pin Controlled by PA20
#define AT91C_PA20_TPK4 ((unsigned int) AT91C_PIO_PA20) // Trace Packet Port 4
#define AT91C_PA20_RD1 ((unsigned int) AT91C_PIO_PA20) // SSC1 Receive Data
#define AT91C_PIO_PA21 ((unsigned int) 1 << 21) // Pin Controlled by PA21
#define AT91C_PA21_TPK5 ((unsigned int) AT91C_PIO_PA21) // Trace Packet Port 5
#define AT91C_PA21_RK1 ((unsigned int) AT91C_PIO_PA21) // SSC1 Receive Clock
#define AT91C_PIO_PA22 ((unsigned int) 1 << 22) // Pin Controlled by PA22
#define AT91C_PA22_TPK6 ((unsigned int) AT91C_PIO_PA22) // Trace Packet Port 6
#define AT91C_PA22_RF1 ((unsigned int) AT91C_PIO_PA22) // SSC1 Receive Frame Sync
#define AT91C_PIO_PA23 ((unsigned int) 1 << 23) // Pin Controlled by PA23
#define AT91C_PA23_TPK7 ((unsigned int) AT91C_PIO_PA23) // Trace Packet Port 7
#define AT91C_PA23_RTS0 ((unsigned int) AT91C_PIO_PA23) // USART0 Ready To Send
#define AT91C_PIO_PA24 ((unsigned int) 1 << 24) // Pin Controlled by PA24
#define AT91C_PA24_TPK8 ((unsigned int) AT91C_PIO_PA24) // Trace Packet Port 8
#define AT91C_PA24_NPCS11 ((unsigned int) AT91C_PIO_PA24) // SPI1 Peripheral Chip Select 1
#define AT91C_PIO_PA25 ((unsigned int) 1 << 25) // Pin Controlled by PA25
#define AT91C_PA25_TPK9 ((unsigned int) AT91C_PIO_PA25) // Trace Packet Port 9
#define AT91C_PA25_NPCS12 ((unsigned int) AT91C_PIO_PA25) // SPI1 Peripheral Chip Select 2
#define AT91C_PIO_PA26 ((unsigned int) 1 << 26) // Pin Controlled by PA26
#define AT91C_PA26_TPK10 ((unsigned int) AT91C_PIO_PA26) // Trace Packet Port 10
#define AT91C_PA26_NPCS13 ((unsigned int) AT91C_PIO_PA26) // SPI1 Peripheral Chip Select 3
#define AT91C_PIO_PA27 ((unsigned int) 1 << 27) // Pin Controlled by PA27
#define AT91C_PA27_TPK11 ((unsigned int) AT91C_PIO_PA27) // Trace Packet Port 11
#define AT91C_PA27_NPCS01 ((unsigned int) AT91C_PIO_PA27) // SPI0 Peripheral Chip Select 1
#define AT91C_PIO_PA28 ((unsigned int) 1 << 28) // Pin Controlled by PA28
#define AT91C_PA28_TPK12 ((unsigned int) AT91C_PIO_PA28) // Trace Packet Port 12
#define AT91C_PA28_NPCS02 ((unsigned int) AT91C_PIO_PA28) // SPI0 Peripheral Chip Select 2
#define AT91C_PIO_PA29 ((unsigned int) 1 << 29) // Pin Controlled by PA29
#define AT91C_PA29_TPK13 ((unsigned int) AT91C_PIO_PA29) // Trace Packet Port 13
#define AT91C_PA29_NPCS03 ((unsigned int) AT91C_PIO_PA29) // SPI0 Peripheral Chip Select 3
#define AT91C_PIO_PA3 ((unsigned int) 1 << 3) // Pin Controlled by PA3
#define AT91C_PA3_NPCS00 ((unsigned int) AT91C_PIO_PA3) // SPI0 Peripheral Chip Select 0
#define AT91C_PIO_PA30 ((unsigned int) 1 << 30) // Pin Controlled by PA30
#define AT91C_PA30_TPK14 ((unsigned int) AT91C_PIO_PA30) // Trace Packet Port 14
#define AT91C_PA30_A23 ((unsigned int) AT91C_PIO_PA30) // Address Bus bit 23
#define AT91C_PIO_PA31 ((unsigned int) 1 << 31) // Pin Controlled by PA31
#define AT91C_PA31_TPK15 ((unsigned int) AT91C_PIO_PA31) // Trace Packet Port 15
#define AT91C_PA31_A24 ((unsigned int) AT91C_PIO_PA31) // Address Bus bit 24
#define AT91C_PIO_PA4 ((unsigned int) 1 << 4) // Pin Controlled by PA4
#define AT91C_PA4_NPCS01 ((unsigned int) AT91C_PIO_PA4) // SPI0 Peripheral Chip Select 1
#define AT91C_PA4_MCDA1 ((unsigned int) AT91C_PIO_PA4) // Multimedia Card A Data 1
#define AT91C_PIO_PA5 ((unsigned int) 1 << 5) // Pin Controlled by PA5
#define AT91C_PA5_NPCS02 ((unsigned int) AT91C_PIO_PA5) // SPI0 Peripheral Chip Select 2
#define AT91C_PA5_MCDA2 ((unsigned int) AT91C_PIO_PA5) // Multimedia Card A Data 2
#define AT91C_PIO_PA6 ((unsigned int) 1 << 6) // Pin Controlled by PA6
#define AT91C_PA6_NPCS03 ((unsigned int) AT91C_PIO_PA6) // SPI0 Peripheral Chip Select 3
#define AT91C_PA6_MCDA3 ((unsigned int) AT91C_PIO_PA6) // Multimedia Card A Data 3
#define AT91C_PIO_PA7 ((unsigned int) 1 << 7) // Pin Controlled by PA7
#define AT91C_PA7_TWD ((unsigned int) AT91C_PIO_PA7) // TWI Two-wire Serial Data
#define AT91C_PA7_PCK0 ((unsigned int) AT91C_PIO_PA7) // PMC Programmable clock Output 0
#define AT91C_PIO_PA8 ((unsigned int) 1 << 8) // Pin Controlled by PA8
#define AT91C_PA8_TWCK ((unsigned int) AT91C_PIO_PA8) // TWI Two-wire Serial Clock
#define AT91C_PA8_PCK1 ((unsigned int) AT91C_PIO_PA8) // PMC Programmable clock Output 1
#define AT91C_PIO_PA9 ((unsigned int) 1 << 9) // Pin Controlled by PA9
#define AT91C_PA9_DRXD ((unsigned int) AT91C_PIO_PA9) // DBGU Debug Receive Data
#define AT91C_PA9_PCK2 ((unsigned int) AT91C_PIO_PA9) // PMC Programmable clock Output 2
#define AT91C_PIO_PB0 ((unsigned int) 1 << 0) // Pin Controlled by PB0
#define AT91C_PB0_LCDVSYNC ((unsigned int) AT91C_PIO_PB0) // LCD Vertical Synchronization
#define AT91C_PIO_PB1 ((unsigned int) 1 << 1) // Pin Controlled by PB1
#define AT91C_PB1_LCDHSYNC ((unsigned int) AT91C_PIO_PB1) // LCD Horizontal Synchronization
#define AT91C_PIO_PB10 ((unsigned int) 1 << 10) // Pin Controlled by PB10
#define AT91C_PB10_LCDD5 ((unsigned int) AT91C_PIO_PB10) // LCD Data Bus Bit 5
#define AT91C_PB10_LCDD10 ((unsigned int) AT91C_PIO_PB10) // LCD Data Bus Bit 10
#define AT91C_PIO_PB11 ((unsigned int) 1 << 11) // Pin Controlled by PB11
#define AT91C_PB11_LCDD6 ((unsigned int) AT91C_PIO_PB11) // LCD Data Bus Bit 6
#define AT91C_PB11_LCDD11 ((unsigned int) AT91C_PIO_PB11) // LCD Data Bus Bit 11
#define AT91C_PIO_PB12 ((unsigned int) 1 << 12) // Pin Controlled by PB12
#define AT91C_PB12_LCDD7 ((unsigned int) AT91C_PIO_PB12) // LCD Data Bus Bit 7
#define AT91C_PB12_LCDD12 ((unsigned int) AT91C_PIO_PB12) // LCD Data Bus Bit 12
#define AT91C_PIO_PB13 ((unsigned int) 1 << 13) // Pin Controlled by PB13
#define AT91C_PB13_LCDD8 ((unsigned int) AT91C_PIO_PB13) // LCD Data Bus Bit 8
#define AT91C_PB13_LCDD13 ((unsigned int) AT91C_PIO_PB13) // LCD Data Bus Bit 13
#define AT91C_PIO_PB14 ((unsigned int) 1 << 14) // Pin Controlled by PB14
#define AT91C_PB14_LCDD9 ((unsigned int) AT91C_PIO_PB14) // LCD Data Bus Bit 9
#define AT91C_PB14_LCDD14 ((unsigned int) AT91C_PIO_PB14) // LCD Data Bus Bit 14
#define AT91C_PIO_PB15 ((unsigned int) 1 << 15) // Pin Controlled by PB15
#define AT91C_PB15_LCDD10 ((unsigned int) AT91C_PIO_PB15) // LCD Data Bus Bit 10
#define AT91C_PB15_LCDD15 ((unsigned int) AT91C_PIO_PB15) // LCD Data Bus Bit 15
#define AT91C_PIO_PB16 ((unsigned int) 1 << 16) // Pin Controlled by PB16
#define AT91C_PB16_LCDD11 ((unsigned int) AT91C_PIO_PB16) // LCD Data Bus Bit 11
#define AT91C_PB16_LCDD19 ((unsigned int) AT91C_PIO_PB16) // LCD Data Bus Bit 19
#define AT91C_PIO_PB17 ((unsigned int) 1 << 17) // Pin Controlled by PB17
#define AT91C_PB17_LCDD12 ((unsigned int) AT91C_PIO_PB17) // LCD Data Bus Bit 12
#define AT91C_PB17_LCDD20 ((unsigned int) AT91C_PIO_PB17) // LCD Data Bus Bit 20
#define AT91C_PIO_PB18 ((unsigned int) 1 << 18) // Pin Controlled by PB18
#define AT91C_PB18_LCDD13 ((unsigned int) AT91C_PIO_PB18) // LCD Data Bus Bit 13
#define AT91C_PB18_LCDD21 ((unsigned int) AT91C_PIO_PB18) // LCD Data Bus Bit 21
#define AT91C_PIO_PB19 ((unsigned int) 1 << 19) // Pin Controlled by PB19
#define AT91C_PB19_LCDD14 ((unsigned int) AT91C_PIO_PB19) // LCD Data Bus Bit 14
#define AT91C_PB19_LCDD22 ((unsigned int) AT91C_PIO_PB19) // LCD Data Bus Bit 22
#define AT91C_PIO_PB2 ((unsigned int) 1 << 2) // Pin Controlled by PB2
#define AT91C_PB2_LCDDOTCK ((unsigned int) AT91C_PIO_PB2) // LCD Dot Clock
#define AT91C_PB2_PCK0 ((unsigned int) AT91C_PIO_PB2) // PMC Programmable clock Output 0
#define AT91C_PIO_PB20 ((unsigned int) 1 << 20) // Pin Controlled by PB20
#define AT91C_PB20_LCDD15 ((unsigned int) AT91C_PIO_PB20) // LCD Data Bus Bit 15
#define AT91C_PB20_LCDD23 ((unsigned int) AT91C_PIO_PB20) // LCD Data Bus Bit 23
#define AT91C_PIO_PB21 ((unsigned int) 1 << 21) // Pin Controlled by PB21
#define AT91C_PB21_TF0 ((unsigned int) AT91C_PIO_PB21) // SSC0 Transmit Frame Sync
#define AT91C_PB21_LCDD16 ((unsigned int) AT91C_PIO_PB21) // LCD Data Bus Bit 16
#define AT91C_PIO_PB22 ((unsigned int) 1 << 22) // Pin Controlled by PB22
#define AT91C_PB22_TK0 ((unsigned int) AT91C_PIO_PB22) // SSC0 Transmit Clock
#define AT91C_PB22_LCDD17 ((unsigned int) AT91C_PIO_PB22) // LCD Data Bus Bit 17
#define AT91C_PIO_PB23 ((unsigned int) 1 << 23) // Pin Controlled by PB23
#define AT91C_PB23_TD0 ((unsigned int) AT91C_PIO_PB23) // SSC0 Transmit Data
#define AT91C_PB23_LCDD18 ((unsigned int) AT91C_PIO_PB23) // LCD Data Bus Bit 18
#define AT91C_PIO_PB24 ((unsigned int) 1 << 24) // Pin Controlled by PB24
#define AT91C_PB24_RD0 ((unsigned int) AT91C_PIO_PB24) // SSC0 Receive Data
#define AT91C_PB24_LCDD19 ((unsigned int) AT91C_PIO_PB24) // LCD Data Bus Bit 19
#define AT91C_PIO_PB25 ((unsigned int) 1 << 25) // Pin Controlled by PB25
#define AT91C_PB25_RK0 ((unsigned int) AT91C_PIO_PB25) // SSC0 Receive Clock
#define AT91C_PB25_LCDD20 ((unsigned int) AT91C_PIO_PB25) // LCD Data Bus Bit 20
#define AT91C_PIO_PB26 ((unsigned int) 1 << 26) // Pin Controlled by PB26
#define AT91C_PB26_RF0 ((unsigned int) AT91C_PIO_PB26) // SSC0 Receive Frame Sync
#define AT91C_PB26_LCDD21 ((unsigned int) AT91C_PIO_PB26) // LCD Data Bus Bit 21
#define AT91C_PIO_PB27 ((unsigned int) 1 << 27) // Pin Controlled by PB27
#define AT91C_PB27_NPCS11 ((unsigned int) AT91C_PIO_PB27) // SPI1 Peripheral Chip Select 1
#define AT91C_PB27_LCDD22 ((unsigned int) AT91C_PIO_PB27) // LCD Data Bus Bit 22
#define AT91C_PIO_PB28 ((unsigned int) 1 << 28) // Pin Controlled by PB28
#define AT91C_PB28_NPCS10 ((unsigned int) AT91C_PIO_PB28) // SPI1 Peripheral Chip Select 0
#define AT91C_PB28_LCDD23 ((unsigned int) AT91C_PIO_PB28) // LCD Data Bus Bit 23
#define AT91C_PIO_PB29 ((unsigned int) 1 << 29) // Pin Controlled by PB29
#define AT91C_PB29_SPCK1 ((unsigned int) AT91C_PIO_PB29) // SPI1 Serial Clock
#define AT91C_PB29_IRQ2 ((unsigned int) AT91C_PIO_PB29) // Interrupt input 2
#define AT91C_PIO_PB3 ((unsigned int) 1 << 3) // Pin Controlled by PB3
#define AT91C_PB3_LCDDEN ((unsigned int) AT91C_PIO_PB3) // LCD Data Enable
#define AT91C_PIO_PB30 ((unsigned int) 1 << 30) // Pin Controlled by PB30
#define AT91C_PB30_MISO1 ((unsigned int) AT91C_PIO_PB30) // SPI1 Master In Slave
#define AT91C_PB30_IRQ1 ((unsigned int) AT91C_PIO_PB30) // Interrupt input 1
#define AT91C_PIO_PB31 ((unsigned int) 1 << 31) // Pin Controlled by PB31
#define AT91C_PB31_MOSI1 ((unsigned int) AT91C_PIO_PB31) // SPI1 Master Out Slave
#define AT91C_PB31_PCK2 ((unsigned int) AT91C_PIO_PB31) // PMC Programmable clock Output 2
#define AT91C_PIO_PB4 ((unsigned int) 1 << 4) // Pin Controlled by PB4
#define AT91C_PB4_LCDCC ((unsigned int) AT91C_PIO_PB4) // LCD Contrast Control
#define AT91C_PB4_LCDD2 ((unsigned int) AT91C_PIO_PB4) // LCD Data Bus Bit 2
#define AT91C_PIO_PB5 ((unsigned int) 1 << 5) // Pin Controlled by PB5
#define AT91C_PB5_LCDD0 ((unsigned int) AT91C_PIO_PB5) // LCD Data Bus Bit 0
#define AT91C_PB5_LCDD3 ((unsigned int) AT91C_PIO_PB5) // LCD Data Bus Bit 3
#define AT91C_PIO_PB6 ((unsigned int) 1 << 6) // Pin Controlled by PB6
#define AT91C_PB6_LCDD1 ((unsigned int) AT91C_PIO_PB6) // LCD Data Bus Bit 1
#define AT91C_PB6_LCDD4 ((unsigned int) AT91C_PIO_PB6) // LCD Data Bus Bit 4
#define AT91C_PIO_PB7 ((unsigned int) 1 << 7) // Pin Controlled by PB7
#define AT91C_PB7_LCDD2 ((unsigned int) AT91C_PIO_PB7) // LCD Data Bus Bit 2
#define AT91C_PB7_LCDD5 ((unsigned int) AT91C_PIO_PB7) // LCD Data Bus Bit 5
#define AT91C_PIO_PB8 ((unsigned int) 1 << 8) // Pin Controlled by PB8
#define AT91C_PB8_LCDD3 ((unsigned int) AT91C_PIO_PB8) // LCD Data Bus Bit 3
#define AT91C_PB8_LCDD6 ((unsigned int) AT91C_PIO_PB8) // LCD Data Bus Bit 6
#define AT91C_PIO_PB9 ((unsigned int) 1 << 9) // Pin Controlled by PB9
#define AT91C_PB9_LCDD4 ((unsigned int) AT91C_PIO_PB9) // LCD Data Bus Bit 4
#define AT91C_PB9_LCDD7 ((unsigned int) AT91C_PIO_PB9) // LCD Data Bus Bit 7
#define AT91C_PIO_PC0 ((unsigned int) 1 << 0) // Pin Controlled by PC0
#define AT91C_PC0_SMOE ((unsigned int) AT91C_PIO_PC0) // SmartMedia Output Enable
#define AT91C_PC0_NCS6 ((unsigned int) AT91C_PIO_PC0) // Chip Select 6
#define AT91C_PIO_PC1 ((unsigned int) 1 << 1) // Pin Controlled by PC1
#define AT91C_PC1_SMWE ((unsigned int) AT91C_PIO_PC1) // SmartMedia Write Enable
#define AT91C_PC1_NCS7 ((unsigned int) AT91C_PIO_PC1) // Chip Select 7
#define AT91C_PIO_PC10 ((unsigned int) 1 << 10) // Pin Controlled by PC10
#define AT91C_PC10_RTS0 ((unsigned int) AT91C_PIO_PC10) // USART0 Ready To Send
#define AT91C_PC10_SCK0 ((unsigned int) AT91C_PIO_PC10) // USART0 Serial Clock
#define AT91C_PIO_PC11 ((unsigned int) 1 << 11) // Pin Controlled by PC11
#define AT91C_PC11_CTS0 ((unsigned int) AT91C_PIO_PC11) // USART0 Clear To Send
#define AT91C_PC11_FIQ ((unsigned int) AT91C_PIO_PC11) // AIC Fast Interrupt Input
#define AT91C_PIO_PC12 ((unsigned int) 1 << 12) // Pin Controlled by PC12
#define AT91C_PC12_TXD1 ((unsigned int) AT91C_PIO_PC12) // USART1 Transmit Data
#define AT91C_PC12_NCS6 ((unsigned int) AT91C_PIO_PC12) // Chip Select 6
#define AT91C_PIO_PC13 ((unsigned int) 1 << 13) // Pin Controlled by PC13
#define AT91C_PC13_RXD1 ((unsigned int) AT91C_PIO_PC13) // USART1 Receive Data
#define AT91C_PC13_NCS7 ((unsigned int) AT91C_PIO_PC13) // Chip Select 7
#define AT91C_PIO_PC14 ((unsigned int) 1 << 14) // Pin Controlled by PC14
#define AT91C_PC14_TXD2 ((unsigned int) AT91C_PIO_PC14) // USART2 Transmit Data
#define AT91C_PC14_NPCS12 ((unsigned int) AT91C_PIO_PC14) // SPI1 Peripheral Chip Select 2
#define AT91C_PIO_PC15 ((unsigned int) 1 << 15) // Pin Controlled by PC15
#define AT91C_PC15_RXD2 ((unsigned int) AT91C_PIO_PC15) // USART2 Receive Data
#define AT91C_PC15_NPCS13 ((unsigned int) AT91C_PIO_PC15) // SPI1 Peripheral Chip Select 3
#define AT91C_PIO_PC16 ((unsigned int) 1 << 16) // Pin Controlled by PC16
#define AT91C_PC16_D16 ((unsigned int) AT91C_PIO_PC16) // Data Bus [16]
#define AT91C_PC16_TCLK0 ((unsigned int) AT91C_PIO_PC16) // Timer Counter 0 external clock input
#define AT91C_PIO_PC17 ((unsigned int) 1 << 17) // Pin Controlled by PC17
#define AT91C_PC17_D17 ((unsigned int) AT91C_PIO_PC17) // Data Bus [17]
#define AT91C_PC17_TCLK1 ((unsigned int) AT91C_PIO_PC17) // Timer Counter 1 external clock input
#define AT91C_PIO_PC18 ((unsigned int) 1 << 18) // Pin Controlled by PC18
#define AT91C_PC18_D18 ((unsigned int) AT91C_PIO_PC18) // Data Bus [18]
#define AT91C_PC18_TCLK2 ((unsigned int) AT91C_PIO_PC18) // Timer Counter 2 external clock input
#define AT91C_PIO_PC19 ((unsigned int) 1 << 19) // Pin Controlled by PC19
#define AT91C_PC19_D19 ((unsigned int) AT91C_PIO_PC19) // Data Bus [19]
#define AT91C_PC19_TIOA0 ((unsigned int) AT91C_PIO_PC19) // Timer Counter 0 Multipurpose Timer I/O Pin A
#define AT91C_PIO_PC2 ((unsigned int) 1 << 2) // Pin Controlled by PC2
#define AT91C_PC2_NWAIT ((unsigned int) AT91C_PIO_PC2) // NWAIT
#define AT91C_PC2_IRQ0 ((unsigned int) AT91C_PIO_PC2) // Interrupt input 0
#define AT91C_PIO_PC20 ((unsigned int) 1 << 20) // Pin Controlled by PC20
#define AT91C_PC20_D20 ((unsigned int) AT91C_PIO_PC20) // Data Bus [20]
#define AT91C_PC20_TIOB0 ((unsigned int) AT91C_PIO_PC20) // Timer Counter 0 Multipurpose Timer I/O Pin B
#define AT91C_PIO_PC21 ((unsigned int) 1 << 21) // Pin Controlled by PC21
#define AT91C_PC21_D21 ((unsigned int) AT91C_PIO_PC21) // Data Bus [21]
#define AT91C_PC21_TIOA1 ((unsigned int) AT91C_PIO_PC21) // Timer Counter 1 Multipurpose Timer I/O Pin A
#define AT91C_PIO_PC22 ((unsigned int) 1 << 22) // Pin Controlled by PC22
#define AT91C_PC22_D22 ((unsigned int) AT91C_PIO_PC22) // Data Bus [22]
#define AT91C_PC22_TIOB1 ((unsigned int) AT91C_PIO_PC22) // Timer Counter 1 Multipurpose Timer I/O Pin B
#define AT91C_PIO_PC23 ((unsigned int) 1 << 23) // Pin Controlled by PC23
#define AT91C_PC23_D23 ((unsigned int) AT91C_PIO_PC23) // Data Bus [23]
#define AT91C_PC23_TIOA2 ((unsigned int) AT91C_PIO_PC23) // Timer Counter 2 Multipurpose Timer I/O Pin A
#define AT91C_PIO_PC24 ((unsigned int) 1 << 24) // Pin Controlled by PC24
#define AT91C_PC24_D24 ((unsigned int) AT91C_PIO_PC24) // Data Bus [24]
#define AT91C_PC24_TIOB2 ((unsigned int) AT91C_PIO_PC24) // Timer Counter 2 Multipurpose Timer I/O Pin B
#define AT91C_PIO_PC25 ((unsigned int) 1 << 25) // Pin Controlled by PC25
#define AT91C_PC25_D25 ((unsigned int) AT91C_PIO_PC25) // Data Bus [25]
#define AT91C_PC25_TF2 ((unsigned int) AT91C_PIO_PC25) // SSC2 Transmit Frame Sync
#define AT91C_PIO_PC26 ((unsigned int) 1 << 26) // Pin Controlled by PC26
#define AT91C_PC26_D26 ((unsigned int) AT91C_PIO_PC26) // Data Bus [26]
#define AT91C_PC26_TK2 ((unsigned int) AT91C_PIO_PC26) // SSC2 Transmit Clock
#define AT91C_PIO_PC27 ((unsigned int) 1 << 27) // Pin Controlled by PC27
#define AT91C_PC27_D27 ((unsigned int) AT91C_PIO_PC27) // Data Bus [27]
#define AT91C_PC27_TD2 ((unsigned int) AT91C_PIO_PC27) // SSC2 Transmit Data
#define AT91C_PIO_PC28 ((unsigned int) 1 << 28) // Pin Controlled by PC28
#define AT91C_PC28_D28 ((unsigned int) AT91C_PIO_PC28) // Data Bus [28]
#define AT91C_PC28_RD2 ((unsigned int) AT91C_PIO_PC28) // SSC2 Receive Data
#define AT91C_PIO_PC29 ((unsigned int) 1 << 29) // Pin Controlled by PC29
#define AT91C_PC29_D29 ((unsigned int) AT91C_PIO_PC29) // Data Bus [29]
#define AT91C_PC29_RK2 ((unsigned int) AT91C_PIO_PC29) // SSC2 Receive Clock
#define AT91C_PIO_PC3 ((unsigned int) 1 << 3) // Pin Controlled by PC3
#define AT91C_PC3_A25_CFRNW ((unsigned int) AT91C_PIO_PC3) // Address Bus[25] / Compact Flash Read Not Write
#define AT91C_PIO_PC30 ((unsigned int) 1 << 30) // Pin Controlled by PC30
#define AT91C_PC30_D30 ((unsigned int) AT91C_PIO_PC30) // Data Bus [30]
#define AT91C_PC30_RF2 ((unsigned int) AT91C_PIO_PC30) // SSC2 Receive Frame Sync
#define AT91C_PIO_PC31 ((unsigned int) 1 << 31) // Pin Controlled by PC31
#define AT91C_PC31_D31 ((unsigned int) AT91C_PIO_PC31) // Data Bus [31]
#define AT91C_PC31_PCK1 ((unsigned int) AT91C_PIO_PC31) // PMC Programmable clock Output 1
#define AT91C_PIO_PC4 ((unsigned int) 1 << 4) // Pin Controlled by PC4
#define AT91C_PC4_NCS4_CFCS0 ((unsigned int) AT91C_PIO_PC4) // Chip Select 4 / CompactFlash Chip Select 0
#define AT91C_PIO_PC5 ((unsigned int) 1 << 5) // Pin Controlled by PC5
#define AT91C_PC5_NCS5_CFCS1 ((unsigned int) AT91C_PIO_PC5) // Chip Select 5 / CompactFlash Chip Select 1
#define AT91C_PIO_PC6 ((unsigned int) 1 << 6) // Pin Controlled by PC6
#define AT91C_PC6_CFCE1 ((unsigned int) AT91C_PIO_PC6) // CompactFlash Chip Enable 1
#define AT91C_PIO_PC7 ((unsigned int) 1 << 7) // Pin Controlled by PC7
#define AT91C_PC7_CFCE2 ((unsigned int) AT91C_PIO_PC7) // CompactFlash Chip Enable 2
#define AT91C_PIO_PC8 ((unsigned int) 1 << 8) // Pin Controlled by PC8
#define AT91C_PC8_TXD0 ((unsigned int) AT91C_PIO_PC8) // USART0 Transmit Data
#define AT91C_PC8_PCK2 ((unsigned int) AT91C_PIO_PC8) // PMC Programmable clock Output 2
#define AT91C_PIO_PC9 ((unsigned int) 1 << 9) // Pin Controlled by PC9
#define AT91C_PC9_RXD0 ((unsigned int) AT91C_PIO_PC9) // USART0 Receive Data
#define AT91C_PC9_PCK3 ((unsigned int) AT91C_PIO_PC9) // PMC Programmable clock Output 3

View file

@ -0,0 +1,183 @@
/*
* Theses defines come from an atmel file that says specifically that it
* has no copyright.
*
* These defines are also usable for the AT91SAM9260 which has pin multiplexing
* that is identical to the AT91SAM9G20.
*/
/* $FreeBSD$ */
#ifndef ARM_AT91_AT91_PIO_SAM9G20_H
#define ARM_AT91_AT91_PIO_SAM9G20_H
#include <arm/at91/at91_pioreg.h>
// *****************************************************************************
// PIO DEFINITIONS FOR AT91SAM9G20
// *****************************************************************************
#define AT91C_PA0_SPI0_MISO (AT91C_PIO_PA0) // SPI 0 Master In Slave
#define AT91C_PA0_MCDB0 (AT91C_PIO_PA0) // Multimedia Card B Data 0
#define AT91C_PA1_SPI0_MOSI (AT91C_PIO_PA1) // SPI 0 Master Out Slave
#define AT91C_PA1_MCCDB (AT91C_PIO_PA1) // Multimedia Card B Command
#define AT91C_PA10_MCDA2 (AT91C_PIO_PA10) // Multimedia Card A Data 2
#define AT91C_PA10_ETX2_0 (AT91C_PIO_PA10) // Ethernet MAC Transmit Data 2
#define AT91C_PA11_MCDA3 (AT91C_PIO_PA11) // Multimedia Card A Data 3
#define AT91C_PA11_ETX3_0 (AT91C_PIO_PA11) // Ethernet MAC Transmit Data 3
#define AT91C_PA12_ETX0 (AT91C_PIO_PA12) // Ethernet MAC Transmit Data 0
#define AT91C_PA13_ETX1 (AT91C_PIO_PA13) // Ethernet MAC Transmit Data 1
#define AT91C_PA14_ERX0 (AT91C_PIO_PA14) // Ethernet MAC Receive Data 0
#define AT91C_PA15_ERX1 (AT91C_PIO_PA15) // Ethernet MAC Receive Data 1
#define AT91C_PA16_ETXEN (AT91C_PIO_PA16) // Ethernet MAC Transmit Enable
#define AT91C_PA17_ERXDV (AT91C_PIO_PA17) // Ethernet MAC Receive Data Valid
#define AT91C_PA18_ERXER (AT91C_PIO_PA18) // Ethernet MAC Receive Error
#define AT91C_PA19_ETXCK (AT91C_PIO_PA19) // Ethernet MAC Transmit Clock/Reference Clock
#define AT91C_PA2_SPI0_SPCK (AT91C_PIO_PA2) // SPI 0 Serial Clock
#define AT91C_PA20_EMDC (AT91C_PIO_PA20) // Ethernet MAC Management Data Clock
#define AT91C_PA21_EMDIO (AT91C_PIO_PA21) // Ethernet MAC Management Data Input/Output
#define AT91C_PA22_ADTRG (AT91C_PIO_PA22) // ADC Trigger
#define AT91C_PA22_ETXER (AT91C_PIO_PA22) // Ethernet MAC Transmikt Coding Error
#define AT91C_PA23_TWD (AT91C_PIO_PA23) // TWI Two-wire Serial Data
#define AT91C_PA23_ETX2_1 (AT91C_PIO_PA23) // Ethernet MAC Transmit Data 2
#define AT91C_PA24_TWCK (AT91C_PIO_PA24) // TWI Two-wire Serial Clock
#define AT91C_PA24_ETX3_1 (AT91C_PIO_PA24) // Ethernet MAC Transmit Data 3
#define AT91C_PA25_TCLK0 (AT91C_PIO_PA25) // Timer Counter 0 external clock input
#define AT91C_PA25_ERX2 (AT91C_PIO_PA25) // Ethernet MAC Receive Data 2
#define AT91C_PA26_TIOA0 (AT91C_PIO_PA26) // Timer Counter 0 Multipurpose Timer I/O Pin A
#define AT91C_PA26_ERX3 (AT91C_PIO_PA26) // Ethernet MAC Receive Data 3
#define AT91C_PA27_TIOA1 (AT91C_PIO_PA27) // Timer Counter 1 Multipurpose Timer I/O Pin A
#define AT91C_PA27_ERXCK (AT91C_PIO_PA27) // Ethernet MAC Receive Clock
#define AT91C_PA28_TIOA2 (AT91C_PIO_PA28) // Timer Counter 2 Multipurpose Timer I/O Pin A
#define AT91C_PA28_ECRS (AT91C_PIO_PA28) // Ethernet MAC Carrier Sense/Carrier Sense and Data Valid
#define AT91C_PA29_SCK1 (AT91C_PIO_PA29) // USART 1 Serial Clock
#define AT91C_PA29_ECOL (AT91C_PIO_PA29) // Ethernet MAC Collision Detected
#define AT91C_PA3_SPI0_NPCS0 (AT91C_PIO_PA3) // SPI 0 Peripheral Chip Select 0
#define AT91C_PA3_MCDB3 (AT91C_PIO_PA3) // Multimedia Card B Data 3
#define AT91C_PA30_SCK2 (AT91C_PIO_PA30) // USART 2 Serial Clock
#define AT91C_PA30_RXD4 (AT91C_PIO_PA30) // USART 4 Receive Data
#define AT91C_PA31_SCK0 (AT91C_PIO_PA31) // USART 0 Serial Clock
#define AT91C_PA31_TXD4 (AT91C_PIO_PA31) // USART 4 Transmit Data
#define AT91C_PA4_RTS2 (AT91C_PIO_PA4) // USART 2 Ready To Send
#define AT91C_PA4_MCDB2 (AT91C_PIO_PA4) // Multimedia Card B Data 2
#define AT91C_PA5_CTS2 (AT91C_PIO_PA5) // USART 2 Clear To Send
#define AT91C_PA5_MCDB1 (AT91C_PIO_PA5) // Multimedia Card B Data 1
#define AT91C_PA6_MCDA0 (AT91C_PIO_PA6) // Multimedia Card A Data 0
#define AT91C_PA7_MCCDA (AT91C_PIO_PA7) // Multimedia Card A Command
#define AT91C_PA8_MCCK (AT91C_PIO_PA8) // Multimedia Card Clock
#define AT91C_PA9_MCDA1 (AT91C_PIO_PA9) // Multimedia Card A Data 1
#define AT91C_PB0_SPI1_MISO (AT91C_PIO_PB0) // SPI 1 Master In Slave
#define AT91C_PB0_TIOA3 (AT91C_PIO_PB0) // Timer Counter 3 Multipurpose Timer I/O Pin A
#define AT91C_PB1_SPI1_MOSI (AT91C_PIO_PB1) // SPI 1 Master Out Slave
#define AT91C_PB1_TIOB3 (AT91C_PIO_PB1) // Timer Counter 3 Multipurpose Timer I/O Pin B
#define AT91C_PB10_TXD3 (AT91C_PIO_PB10) // USART 3 Transmit Data
#define AT91C_PB10_ISI_D8 (AT91C_PIO_PB10) // Image Sensor Data 8
#define AT91C_PB11_RXD3 (AT91C_PIO_PB11) // USART 3 Receive Data
#define AT91C_PB11_ISI_D9 (AT91C_PIO_PB11) // Image Sensor Data 9
#define AT91C_PB12_TXD5 (AT91C_PIO_PB12) // USART 5 Transmit Data
#define AT91C_PB12_ISI_D10 (AT91C_PIO_PB12) // Image Sensor Data 10
#define AT91C_PB13_RXD5 (AT91C_PIO_PB13) // USART 5 Receive Data
#define AT91C_PB13_ISI_D11 (AT91C_PIO_PB13) // Image Sensor Data 11
#define AT91C_PB14_DRXD (AT91C_PIO_PB14) // DBGU Debug Receive Data
#define AT91C_PB15_DTXD (AT91C_PIO_PB15) // DBGU Debug Transmit Data
#define AT91C_PB16_TK0 (AT91C_PIO_PB16) // SSC0 Transmit Clock
#define AT91C_PB16_TCLK3 (AT91C_PIO_PB16) // Timer Counter 3 external clock input
#define AT91C_PB17_TF0 (AT91C_PIO_PB17) // SSC0 Transmit Frame Sync
#define AT91C_PB17_TCLK4 (AT91C_PIO_PB17) // Timer Counter 4 external clock input
#define AT91C_PB18_TD0 (AT91C_PIO_PB18) // SSC0 Transmit data
#define AT91C_PB18_TIOB4 (AT91C_PIO_PB18) // Timer Counter 4 Multipurpose Timer I/O Pin B
#define AT91C_PB19_RD0 (AT91C_PIO_PB19) // SSC0 Receive Data
#define AT91C_PB19_TIOB5 (AT91C_PIO_PB19) // Timer Counter 5 Multipurpose Timer I/O Pin B
#define AT91C_PB2_SPI1_SPCK (AT91C_PIO_PB2) // SPI 1 Serial Clock
#define AT91C_PB2_TIOA4 (AT91C_PIO_PB2) // Timer Counter 4 Multipurpose Timer I/O Pin A
#define AT91C_PB20_RK0 (AT91C_PIO_PB20) // SSC0 Receive Clock
#define AT91C_PB20_ISI_D0 (AT91C_PIO_PB20) // Image Sensor Data 0
#define AT91C_PB21_RF0 (AT91C_PIO_PB21) // SSC0 Receive Frame Sync
#define AT91C_PB21_ISI_D1 (AT91C_PIO_PB21) // Image Sensor Data 1
#define AT91C_PB22_DSR0 (AT91C_PIO_PB22) // USART 0 Data Set ready
#define AT91C_PB22_ISI_D2 (AT91C_PIO_PB22) // Image Sensor Data 2
#define AT91C_PB23_DCD0 (AT91C_PIO_PB23) // USART 0 Data Carrier Detect
#define AT91C_PB23_ISI_D3 (AT91C_PIO_PB23) // Image Sensor Data 3
#define AT91C_PB24_DTR0 (AT91C_PIO_PB24) // USART 0 Data Terminal ready
#define AT91C_PB24_ISI_D4 (AT91C_PIO_PB24) // Image Sensor Data 4
#define AT91C_PB25_RI0 (AT91C_PIO_PB25) // USART 0 Ring Indicator
#define AT91C_PB25_ISI_D5 (AT91C_PIO_PB25) // Image Sensor Data 5
#define AT91C_PB26_RTS0 (AT91C_PIO_PB26) // USART 0 Ready To Send
#define AT91C_PB26_ISI_D6 (AT91C_PIO_PB26) // Image Sensor Data 6
#define AT91C_PB27_CTS0 (AT91C_PIO_PB27) // USART 0 Clear To Send
#define AT91C_PB27_ISI_D7 (AT91C_PIO_PB27) // Image Sensor Data 7
#define AT91C_PB28_RTS1 (AT91C_PIO_PB28) // USART 1 Ready To Send
#define AT91C_PB28_ISI_PCK (AT91C_PIO_PB28) // Image Sensor Data Clock
#define AT91C_PB29_CTS1 (AT91C_PIO_PB29) // USART 1 Clear To Send
#define AT91C_PB29_ISI_VSYNC (AT91C_PIO_PB29) // Image Sensor Vertical Synchro
#define AT91C_PB3_SPI1_NPCS0 (AT91C_PIO_PB3) // SPI 1 Peripheral Chip Select 0
#define AT91C_PB3_TIOA5 (AT91C_PIO_PB3) // Timer Counter 5 Multipurpose Timer I/O Pin A
#define AT91C_PB30_PCK0_0 (AT91C_PIO_PB30) // PMC Programmable Clock Output 0
#define AT91C_PB30_ISI_HSYNC (AT91C_PIO_PB30) // Image Sensor Horizontal Synchro
#define AT91C_PB31_PCK1_0 (AT91C_PIO_PB31) // PMC Programmable Clock Output 1
#define AT91C_PB31_ISI_MCK (AT91C_PIO_PB31) // Image Sensor Reference Clock
#define AT91C_PB4_TXD0 (AT91C_PIO_PB4) // USART 0 Transmit Data
#define AT91C_PB5_RXD0 (AT91C_PIO_PB5) // USART 0 Receive Data
#define AT91C_PB6_TXD1 (AT91C_PIO_PB6) // USART 1 Transmit Data
#define AT91C_PB6_TCLK1 (AT91C_PIO_PB6) // Timer Counter 1 external clock input
#define AT91C_PB7_RXD1 (AT91C_PIO_PB7) // USART 1 Receive Data
#define AT91C_PB7_TCLK2 (AT91C_PIO_PB7) // Timer Counter 2 external clock input
#define AT91C_PB8_TXD2 (AT91C_PIO_PB8) // USART 2 Transmit Data
#define AT91C_PB9_RXD2 (AT91C_PIO_PB9) // USART 2 Receive Data
#define AT91C_PC0_AD0 (AT91C_PIO_PC0) // ADC Analog Input 0
#define AT91C_PC0_SCK3 (AT91C_PIO_PC0) // USART 3 Serial Clock
#define AT91C_PC1_AD1 (AT91C_PIO_PC1) // ADC Analog Input 1
#define AT91C_PC1_PCK0_1 (AT91C_PIO_PC1) // PMC Programmable Clock Output 0
#define AT91C_PC10_A25_CFR NW (AT91C_PIO_PC10) // Address Bus[25]
#define AT91C_PC10_CTS3 (AT91C_PIO_PC10) // USART 3 Clear To Send
#define AT91C_PC11_NCS2 (AT91C_PIO_PC11) // Chip Select Line 2
#define AT91C_PC11_SPI0_NPCS1 (AT91C_PIO_PC11) // SPI 0 Peripheral Chip Select 1
#define AT91C_PC12_IRQ0 (AT91C_PIO_PC12) // External Interrupt 0
#define AT91C_PC12_NCS7 (AT91C_PIO_PC12) // Chip Select Line 7
#define AT91C_PC13_FIQ (AT91C_PIO_PC13) // AIC Fast Interrupt Input
#define AT91C_PC13_NCS6 (AT91C_PIO_PC13) // Chip Select Line 6
#define AT91C_PC14_NCS3_NANDCS (AT91C_PIO_PC14) // Chip Select Line 3
#define AT91C_PC14_IRQ2 (AT91C_PIO_PC14) // External Interrupt 2
#define AT91C_PC15_NWAIT (AT91C_PIO_PC15) // External Wait Signal
#define AT91C_PC15_IRQ1 (AT91C_PIO_PC15) // External Interrupt 1
#define AT91C_PC16_D16 (AT91C_PIO_PC16) // Data Bus[16]
#define AT91C_PC16_SPI0_NPCS2 (AT91C_PIO_PC16) // SPI 0 Peripheral Chip Select 2
#define AT91C_PC17_D17 (AT91C_PIO_PC17) // Data Bus[17]
#define AT91C_PC17_SPI0_NPCS3 (AT91C_PIO_PC17) // SPI 0 Peripheral Chip Select 3
#define AT91C_PC18_D18 (AT91C_PIO_PC18) // Data Bus[18]
#define AT91C_PC18_SPI1_NPCS1_1 (AT91C_PIO_PC18) // SPI 1 Peripheral Chip Select 1
#define AT91C_PC19_D19 (AT91C_PIO_PC19) // Data Bus[19]
#define AT91C_PC19_SPI1_NPCS2_1 (AT91C_PIO_PC19) // SPI 1 Peripheral Chip Select 2
#define AT91C_PC2_AD2 (AT91C_PIO_PC2) // ADC Analog Input 2
#define AT91C_PC2_PCK1_1 (AT91C_PIO_PC2) // PMC Programmable Clock Output 1
#define AT91C_PC20_D20 (AT91C_PIO_PC20) // Data Bus[20]
#define AT91C_PC20_SPI1_NPCS3_1 (AT91C_PIO_PC20) // SPI 1 Peripheral Chip Select 3
#define AT91C_PC21_D21 (AT91C_PIO_PC21) // Data Bus[21]
#define AT91C_PC21_EF100 (AT91C_PIO_PC21) // Ethernet MAC Force 100 Mbits/sec
#define AT91C_PC22_D22 (AT91C_PIO_PC22) // Data Bus[22]
#define AT91C_PC22_TCLK5 (AT91C_PIO_PC22) // Timer Counter 5 external clock input
#define AT91C_PC23_D23 (AT91C_PIO_PC23) // Data Bus[23]
#define AT91C_PC24_D24 (AT91C_PIO_PC24) // Data Bus[24]
#define AT91C_PC25_D25 (AT91C_PIO_PC25) // Data Bus[25]
#define AT91C_PC26_D26 (AT91C_PIO_PC26) // Data Bus[26]
#define AT91C_PC27_D27 (AT91C_PIO_PC27) // Data Bus[27]
#define AT91C_PC28_D28 (AT91C_PIO_PC28) // Data Bus[28]
#define AT91C_PC29_D29 (AT91C_PIO_PC29) // Data Bus[29]
#define AT91C_PC3_AD3 (AT91C_PIO_PC3) // ADC Analog Input 3
#define AT91C_PC3_SPI1_NPCS3_0 (AT91C_PIO_PC3) // SPI 1 Peripheral Chip Select 3
#define AT91C_PC30_D30 (AT91C_PIO_PC30) // Data Bus[30]
#define AT91C_PC31_D31 (AT91C_PIO_PC31) // Data Bus[31]
#define AT91C_PC4_A23 (AT91C_PIO_PC4) // Address Bus[23]
#define AT91C_PC4_SPI1_NPCS2_0 (AT91C_PIO_PC4) // SPI 1 Peripheral Chip Select 2
#define AT91C_PC5_A24 (AT91C_PIO_PC5) // Address Bus[24]
#define AT91C_PC5_SPI1_NPCS1_0 (AT91C_PIO_PC5) // SPI 1 Peripheral Chip Select 1
#define AT91C_PC6_TIOB2 (AT91C_PIO_PC6) // Timer Counter 2 Multipurpose Timer I/O Pin B
#define AT91C_PC6_CFCE1 (AT91C_PIO_PC6) // Compact Flash Enable 1
#define AT91C_PC7_TIOB1 (AT91C_PIO_PC7) // Timer Counter 1 Multipurpose Timer I/O Pin B
#define AT91C_PC7_CFCE2 (AT91C_PIO_PC7) // Compact Flash Enable 2
#define AT91C_PC8_NCS4_CFCS0 (AT91C_PIO_PC8) // Chip Select Line 4
#define AT91C_PC8_RTS3 (AT91C_PIO_PC8) // USART 3 Ready To Send
#define AT91C_PC9_NCS5_CFCS1 (AT91C_PIO_PC9) // Chip Select Line 5
#define AT91C_PC9_TIOB0 (AT91C_PIO_PC9) // Timer Counter 0 Multipurpose Timer I/O Pin B
#endif /* ARM_AT91_AT91_PIO_SAM9G20_H */

View file

@ -66,4 +66,101 @@
#define PIO_OWSR 0xa8 /* PIO Output Write Status Register */
/* 0xac reserved */
#define AT91C_PIO_PA0 ((unsigned int) 1 << 0) // Pin Controlled by PA0
#define AT91C_PIO_PA1 ((unsigned int) 1 << 1) // Pin Controlled by PA1
#define AT91C_PIO_PA2 ((unsigned int) 1 << 2) // Pin Controlled by PA2
#define AT91C_PIO_PA3 ((unsigned int) 1 << 3) // Pin Controlled by PA3
#define AT91C_PIO_PA4 ((unsigned int) 1 << 4) // Pin Controlled by PA4
#define AT91C_PIO_PA5 ((unsigned int) 1 << 5) // Pin Controlled by PA5
#define AT91C_PIO_PA6 ((unsigned int) 1 << 6) // Pin Controlled by PA6
#define AT91C_PIO_PA7 ((unsigned int) 1 << 7) // Pin Controlled by PA7
#define AT91C_PIO_PA8 ((unsigned int) 1 << 8) // Pin Controlled by PA8
#define AT91C_PIO_PA9 ((unsigned int) 1 << 9) // Pin Controlled by PA9
#define AT91C_PIO_PA10 ((unsigned int) 1 << 10) // Pin Controlled by PA10
#define AT91C_PIO_PA11 ((unsigned int) 1 << 11) // Pin Controlled by PA11
#define AT91C_PIO_PA12 ((unsigned int) 1 << 12) // Pin Controlled by PA12
#define AT91C_PIO_PA13 ((unsigned int) 1 << 13) // Pin Controlled by PA13
#define AT91C_PIO_PA14 ((unsigned int) 1 << 14) // Pin Controlled by PA14
#define AT91C_PIO_PA15 ((unsigned int) 1 << 15) // Pin Controlled by PA15
#define AT91C_PIO_PA16 ((unsigned int) 1 << 16) // Pin Controlled by PA16
#define AT91C_PIO_PA17 ((unsigned int) 1 << 17) // Pin Controlled by PA17
#define AT91C_PIO_PA18 ((unsigned int) 1 << 18) // Pin Controlled by PA18
#define AT91C_PIO_PA19 ((unsigned int) 1 << 19) // Pin Controlled by PA19
#define AT91C_PIO_PA20 ((unsigned int) 1 << 20) // Pin Controlled by PA20
#define AT91C_PIO_PA21 ((unsigned int) 1 << 21) // Pin Controlled by PA21
#define AT91C_PIO_PA22 ((unsigned int) 1 << 22) // Pin Controlled by PA22
#define AT91C_PIO_PA23 ((unsigned int) 1 << 23) // Pin Controlled by PA23
#define AT91C_PIO_PA24 ((unsigned int) 1 << 24) // Pin Controlled by PA24
#define AT91C_PIO_PA25 ((unsigned int) 1 << 25) // Pin Controlled by PA25
#define AT91C_PIO_PA26 ((unsigned int) 1 << 26) // Pin Controlled by PA26
#define AT91C_PIO_PA27 ((unsigned int) 1 << 27) // Pin Controlled by PA27
#define AT91C_PIO_PA28 ((unsigned int) 1 << 28) // Pin Controlled by PA28
#define AT91C_PIO_PA29 ((unsigned int) 1 << 29) // Pin Controlled by PA29
#define AT91C_PIO_PA30 ((unsigned int) 1 << 30) // Pin Controlled by PA30
#define AT91C_PIO_PA31 ((unsigned int) 1 << 31) // Pin Controlled by PA31
#define AT91C_PIO_PB0 ((unsigned int) 1 << 0) // Pin Controlled by PB0
#define AT91C_PIO_PB1 ((unsigned int) 1 << 1) // Pin Controlled by PB1
#define AT91C_PIO_PB2 ((unsigned int) 1 << 2) // Pin Controlled by PB2
#define AT91C_PIO_PB3 ((unsigned int) 1 << 3) // Pin Controlled by PB3
#define AT91C_PIO_PB4 ((unsigned int) 1 << 4) // Pin Controlled by PB4
#define AT91C_PIO_PB5 ((unsigned int) 1 << 5) // Pin Controlled by PB5
#define AT91C_PIO_PB6 ((unsigned int) 1 << 6) // Pin Controlled by PB6
#define AT91C_PIO_PB7 ((unsigned int) 1 << 7) // Pin Controlled by PB7
#define AT91C_PIO_PB8 ((unsigned int) 1 << 8) // Pin Controlled by PB8
#define AT91C_PIO_PB9 ((unsigned int) 1 << 9) // Pin Controlled by PB9
#define AT91C_PIO_PB10 ((unsigned int) 1 << 10) // Pin Controlled by PB10
#define AT91C_PIO_PB11 ((unsigned int) 1 << 11) // Pin Controlled by PB11
#define AT91C_PIO_PB12 ((unsigned int) 1 << 12) // Pin Controlled by PB12
#define AT91C_PIO_PB13 ((unsigned int) 1 << 13) // Pin Controlled by PB13
#define AT91C_PIO_PB14 ((unsigned int) 1 << 14) // Pin Controlled by PB14
#define AT91C_PIO_PB15 ((unsigned int) 1 << 15) // Pin Controlled by PB15
#define AT91C_PIO_PB16 ((unsigned int) 1 << 16) // Pin Controlled by PB16
#define AT91C_PIO_PB17 ((unsigned int) 1 << 17) // Pin Controlled by PB17
#define AT91C_PIO_PB18 ((unsigned int) 1 << 18) // Pin Controlled by PB18
#define AT91C_PIO_PB19 ((unsigned int) 1 << 19) // Pin Controlled by PB19
#define AT91C_PIO_PB20 ((unsigned int) 1 << 20) // Pin Controlled by PB20
#define AT91C_PIO_PB21 ((unsigned int) 1 << 21) // Pin Controlled by PB21
#define AT91C_PIO_PB22 ((unsigned int) 1 << 22) // Pin Controlled by PB22
#define AT91C_PIO_PB23 ((unsigned int) 1 << 23) // Pin Controlled by PB23
#define AT91C_PIO_PB24 ((unsigned int) 1 << 24) // Pin Controlled by PB24
#define AT91C_PIO_PB25 ((unsigned int) 1 << 25) // Pin Controlled by PB25
#define AT91C_PIO_PB26 ((unsigned int) 1 << 26) // Pin Controlled by PB26
#define AT91C_PIO_PB27 ((unsigned int) 1 << 27) // Pin Controlled by PB27
#define AT91C_PIO_PB28 ((unsigned int) 1 << 28) // Pin Controlled by PB28
#define AT91C_PIO_PB29 ((unsigned int) 1 << 29) // Pin Controlled by PB29
#define AT91C_PIO_PB30 ((unsigned int) 1 << 30) // Pin Controlled by PB30
#define AT91C_PIO_PB31 ((unsigned int) 1 << 31) // Pin Controlled by PB31
#define AT91C_PIO_PC0 ((unsigned int) 1 << 0) // Pin Controlled by PC0
#define AT91C_PIO_PC1 ((unsigned int) 1 << 1) // Pin Controlled by PC1
#define AT91C_PIO_PC2 ((unsigned int) 1 << 2) // Pin Controlled by PC2
#define AT91C_PIO_PC3 ((unsigned int) 1 << 3) // Pin Controlled by PC3
#define AT91C_PIO_PC4 ((unsigned int) 1 << 4) // Pin Controlled by PC4
#define AT91C_PIO_PC5 ((unsigned int) 1 << 5) // Pin Controlled by PC5
#define AT91C_PIO_PC6 ((unsigned int) 1 << 6) // Pin Controlled by PC6
#define AT91C_PIO_PC7 ((unsigned int) 1 << 7) // Pin Controlled by PC7
#define AT91C_PIO_PC8 ((unsigned int) 1 << 8) // Pin Controlled by PC8
#define AT91C_PIO_PC9 ((unsigned int) 1 << 9) // Pin Controlled by PC9
#define AT91C_PIO_PC10 ((unsigned int) 1 << 10) // Pin Controlled by PC10
#define AT91C_PIO_PC11 ((unsigned int) 1 << 11) // Pin Controlled by PC11
#define AT91C_PIO_PC12 ((unsigned int) 1 << 12) // Pin Controlled by PC12
#define AT91C_PIO_PC13 ((unsigned int) 1 << 13) // Pin Controlled by PC13
#define AT91C_PIO_PC14 ((unsigned int) 1 << 14) // Pin Controlled by PC14
#define AT91C_PIO_PC15 ((unsigned int) 1 << 15) // Pin Controlled by PC15
#define AT91C_PIO_PC16 ((unsigned int) 1 << 16) // Pin Controlled by PC16
#define AT91C_PIO_PC17 ((unsigned int) 1 << 17) // Pin Controlled by PC17
#define AT91C_PIO_PC18 ((unsigned int) 1 << 18) // Pin Controlled by PC18
#define AT91C_PIO_PC19 ((unsigned int) 1 << 19) // Pin Controlled by PC19
#define AT91C_PIO_PC20 ((unsigned int) 1 << 20) // Pin Controlled by PC20
#define AT91C_PIO_PC21 ((unsigned int) 1 << 21) // Pin Controlled by PC21
#define AT91C_PIO_PC22 ((unsigned int) 1 << 22) // Pin Controlled by PC22
#define AT91C_PIO_PC23 ((unsigned int) 1 << 23) // Pin Controlled by PC23
#define AT91C_PIO_PC24 ((unsigned int) 1 << 24) // Pin Controlled by PC24
#define AT91C_PIO_PC25 ((unsigned int) 1 << 25) // Pin Controlled by PC25
#define AT91C_PIO_PC26 ((unsigned int) 1 << 26) // Pin Controlled by PC26
#define AT91C_PIO_PC27 ((unsigned int) 1 << 27) // Pin Controlled by PC27
#define AT91C_PIO_PC28 ((unsigned int) 1 << 28) // Pin Controlled by PC28
#define AT91C_PIO_PC29 ((unsigned int) 1 << 29) // Pin Controlled by PC29
#define AT91C_PIO_PC30 ((unsigned int) 1 << 30) // Pin Controlled by PC30
#define AT91C_PIO_PC31 ((unsigned int) 1 << 31) // Pin Controlled by PC31
#endif /* ARM_AT91_AT91_PIOREG_H */

View file

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2010 Yohanes Nugroho. All rights reserved.
* Copyright (c) 2009 Gallon Sylvestre. All rights reserved.
* Copyright (c) 2010 Greg Ansley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -24,110 +25,117 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/time.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/systm.h>
#include <sys/rman.h>
#include <sys/time.h>
#include <sys/timetc.h>
#include <sys/watchdog.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <machine/resource.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_pitreg.h>
#include <arm/at91/at91_pmcvar.h>
#include <arm/at91/at91sam9g20reg.h>
__FBSDID("$FreeBSD$");
static struct pit_softc {
struct resource *mem_res; /* Memory resource */
void *intrhand; /* Interrupt handle */
device_t sc_dev;
} *sc;
static struct at91pit_softc {
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
device_t sc_dev;
} *pit_softc;
static uint32_t timecount = 0;
#define RD4(off) \
bus_space_read_4(pit_softc->sc_st, pit_softc->sc_sh, (off))
#define WR4(off, val) \
bus_space_write_4(pit_softc->sc_st, pit_softc->sc_sh, (off), (val))
static inline uint32_t
RD4(struct pit_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->mem_res, off));
}
static inline void
WR4(struct pit_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
static unsigned at91pit_get_timecount(struct timecounter *tc);
static int clock_intr(void *arg);
static int pit_intr(void *arg);
#ifndef PIT_PRESCALE
#define PIT_PRESCALE (16)
#endif
static struct timecounter at91pit_timecounter = {
at91pit_get_timecount, /* get_timecount */
NULL, /* no poll_pps */
0xffffffffu, /* counter mask */
0, /* frequency */
"AT91SAM9261 timer", /* name */
0xffffffff, /* counter mask */
0 / PIT_PRESCALE, /* frequency */
"AT91SAM9 timer", /* name */
1000 /* quality */
};
uint32_t
at91_pit_base(void);
uint32_t
at91_pit_size(void);
static int
at91pit_probe(device_t dev)
{
device_set_desc(dev, "PIT");
return (0);
}
uint32_t
at91_pit_base(void)
{
return (AT91SAM9G20_PIT_BASE);
if (at91_is_sam9()) {
device_set_desc(dev, "AT91SAM9 PIT");
return (0);
}
return (ENXIO);
}
uint32_t
at91_pit_size(void)
{
return (AT91SAM9G20_PIT_SIZE);
}
static int pit_rate;
static int pit_cycle;
static int pit_counter;
static int
at91pit_attach(device_t dev)
{
struct at91_softc *sc = device_get_softc(device_get_parent(dev));
struct resource *irq;
int rid = 0;
void *ih;
int rid, err = 0;
struct at91_softc *at91_sc;
struct resource *irq;
pit_softc = device_get_softc(dev);
pit_softc->sc_st = sc->sc_st;
pit_softc->sc_dev = dev;
if (bus_space_subregion(sc->sc_st, sc->sc_sh, at91_pit_base(),
at91_pit_size(), &pit_softc->sc_sh) != 0)
panic("couldn't subregion pit registers");
at91_sc = device_get_softc(device_get_parent(dev));
sc = device_get_softc(dev);
sc->sc_dev = dev;
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
panic("couldn't allocate register resources");
rid = 0;
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1, 1, 1,
RF_ACTIVE | RF_SHAREABLE);
if (!irq)
panic("Unable to allocate IRQ for the system timer");
else
bus_setup_intr(dev, irq, INTR_TYPE_CLK,
clock_intr, NULL, NULL, &ih);
if (!irq) {
device_printf(dev, "could not allocate interrupt resources.\n");
err = ENOMEM;
goto out;
}
device_printf(dev, "AT91SAM9x pit registered\n");
return (0);
/* Activate the interrupt. */
err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, pit_intr,
NULL, NULL, &ih);
at91pit_timecounter.tc_frequency = at91_master_clock / PIT_PRESCALE;
tc_init(&at91pit_timecounter);
//Enable the PIT here.
WR4(sc, PIT_MR,
PIT_PIV(at91_master_clock / PIT_PRESCALE / hz) |
PIT_EN | PIT_IEN);
out:
return (err);
}
static device_method_t at91pit_methods[] = {
@ -139,7 +147,7 @@ static device_method_t at91pit_methods[] = {
static driver_t at91pit_driver = {
"at91_pit",
at91pit_methods,
sizeof(struct at91pit_softc),
sizeof(struct pit_softc),
};
static devclass_t at91pit_devclass;
@ -147,52 +155,58 @@ static devclass_t at91pit_devclass;
DRIVER_MODULE(at91_pit, atmelarm, at91pit_driver, at91pit_devclass, 0, 0);
static int
clock_intr(void *arg)
pit_intr(void *arg)
{
struct trapframe *fp = arg;
uint32_t icnt;
if (RD4(sc, PIT_SR) & PIT_PITS_DONE) {
icnt = RD4(sc, PIT_PIVR) >> 20;
/* Just add in the overflows we just read */
timecount += PIT_PIV(RD4(sc, PIT_MR)) * icnt;
if (RD4(PIT_SR) & PIT_PITS_DONE) {
uint32_t pivr = RD4(PIT_PIVR);
if (PIT_CNT(pivr)>1) {
printf("cnt = %d\n", PIT_CNT(pivr));
}
pit_counter += pit_cycle;
hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
return (FILTER_HANDLED);
}
return (FILTER_STRAY);
}
static unsigned
static unsigned
at91pit_get_timecount(struct timecounter *tc)
{
return pit_counter;
uint32_t piir, icnt;
piir = RD4(sc, PIT_PIIR); /* Current count | over flows */
icnt = piir >> 20; /* Overflows */
return (timecount + PIT_PIV(piir) + PIT_PIV(RD4(sc, PIT_MR)) * icnt);
}
/*todo: review this*/
void
DELAY(int n)
DELAY(int us)
{
u_int32_t start, end, cur;
int32_t cnt, last, piv;
uint64_t pit_freq;
const uint64_t mhz = 1E6;
start = RD4(PIT_PIIR);
n = (n * 1000) / (at91_master_clock / 12);
if (n <= 0)
n = 1;
end = (start + n);
cur = start;
if (start > end) {
while (cur >= start || cur < end)
cur = RD4(PIT_PIIR);
} else {
while (cur < end)
cur = RD4(PIT_PIIR);
last = PIT_PIV(RD4(sc, PIT_PIIR));
/* Max delay ~= 260s. @ 133Mhz */
pit_freq = at91_master_clock / PIT_PRESCALE;
cnt = ((pit_freq * us) + (mhz -1)) / mhz;
cnt = (cnt <= 0) ? 1 : cnt;
while (cnt > 0) {
piv = PIT_PIV(RD4(sc, PIT_PIIR));
cnt -= piv - last ;
if (piv < last)
cnt -= PIT_PIV(~0u) - last;
last = piv;
}
}
/*
* The 3 next functions must be implement with the futur PLL code.
* The 3 next functions must be implement with the future PLL code.
*/
void
cpu_startprofclock(void)
@ -204,30 +218,7 @@ cpu_stopprofclock(void)
{
}
#define HZ 100
void
cpu_initclocks(void)
{
struct at91_pmc_clock *master;
master = at91_pmc_clock_ref("mck");
pit_rate = master->hz / 16;
pit_cycle = (pit_rate + HZ/2) / HZ;
at91pit_timecounter.tc_frequency = pit_rate;
WR4(PIT_MR, 0);
while (PIT_PIV(RD4(PIT_PIVR)) != 0);
WR4(PIT_MR, (pit_cycle - 1) | PIT_IEN | PIT_EN);
tc_init(&at91pit_timecounter);
}
void
cpu_reset(void)
{
*(volatile int *)(AT91SAM9G20_BASE + AT91SAM9G20_RSTC_BASE +
RSTC_CR) = RSTC_PROCRST | RSTC_PERRST | RSTC_KEY;
while (1)
continue;
}

View file

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2006 M. Warner Losh. All rights reserved.
* Copyright (c) 2010 Greg Ansley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -23,14 +24,13 @@
* SUCH DAMAGE.
*/
#include "opt_at91.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/time.h>
#include <sys/bus.h>
@ -44,8 +44,8 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
@ -59,9 +59,13 @@ static struct at91_pmc_softc {
uint32_t pllb_init;
} *pmc_softc;
MALLOC_DECLARE(M_PMC);
MALLOC_DEFINE(M_PMC, "at91_pmc_clocks", "AT91 PMC Clock descriptors");
static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int);
static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int);
static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int);
static void at91_pmc_clock_alias(const char *name, const char *alias);
static struct at91_pmc_clock slck = {
.name = "slck", // 32,768 Hz slow clock
@ -71,6 +75,10 @@ static struct at91_pmc_clock slck = {
.primary = 1,
};
/*
* NOTE: Clocks for "ordinary peripheral" devices e.g. spi0, udp0, uhp0 etc.
* are now created automatically. Only "system" clocks need be defined here.
*/
static struct at91_pmc_clock main_ck = {
.name = "main", // Main clock
.refcnt = 0,
@ -115,60 +123,20 @@ static struct at91_pmc_clock uhpck = {
};
static struct at91_pmc_clock mck = {
.name = "mck",
.name = "mck", // Master (Peripheral) Clock
.pmc_mask = PMC_IER_MCKRDY,
.refcnt = 0,
};
#ifdef AT91SAM9G20
#define IRQ_UDP AT91SAM9G20_IRQ_UDP
#define IRQ_UHP AT91SAM9G20_IRQ_UHP
#else
#define IRQ_UDP AT91RM92_IRQ_UDP
#define IRQ_UHP AT91RM92_IRQ_UHP
#endif /* AT91SAM9G20 */
static struct at91_pmc_clock udc_clk = {
.name = "udc_clk",
.parent = &mck,
.pmc_mask = 1 << IRQ_UDP,
.set_mode = &at91_pmc_set_periph_mode
static struct at91_pmc_clock cpu = {
.name = "cpu", // CPU Clock
.parent = &plla,
.pmc_mask = PMC_SCER_PCK,
.refcnt = 0,
};
static struct at91_pmc_clock ohci_clk = {
.name = "ohci_clk",
.parent = &mck,
.pmc_mask = 1 << IRQ_UHP,
.set_mode = &at91_pmc_set_periph_mode
};
#ifdef AT91SAM9G20
static struct at91_pmc_clock macb_clk = {
.name = "macb_clk",
.parent = &mck,
.pmc_mask = 1 << 21,
.set_mode = &at91_pmc_set_periph_mode
};
static struct at91_pmc_clock spi0_clk = {
.name = "spi0_clk",
.parent = &mck,
.pmc_mask = 1 << 12,
.set_mode = &at91_pmc_set_periph_mode
};
static struct at91_pmc_clock spi1_clk = {
.name = "spi1_clk",
.parent = &mck,
.pmc_mask = 1 << 13,
.set_mode = &at91_pmc_set_periph_mode
};
#endif /* AT91SAM9G20 */
static struct at91_pmc_clock *const clock_list[] = {
/* "+32" or the automatic peripheral clocks */
static struct at91_pmc_clock *clock_list[16+32] = {
&slck,
&main_ck,
&plla,
@ -176,13 +144,7 @@ static struct at91_pmc_clock *const clock_list[] = {
&udpck,
&uhpck,
&mck,
&udc_clk,
#ifdef AT91SAM9G20
&macb_clk,
&spi0_clk,
&spi1_clk,
#endif /* AT91SAM9G20 */
&ohci_clk
&cpu
};
#if !defined(AT91C_MAIN_CLOCK)
@ -200,7 +162,7 @@ static const unsigned int at91_mainf_tbl[] = {
static inline uint32_t
RD4(struct at91_pmc_softc *sc, bus_size_t off)
{
return bus_read_4(sc->mem_res, off);
return (bus_read_4(sc->mem_res, off));
}
static inline void
@ -209,7 +171,7 @@ WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val)
bus_write_4(sc->mem_res, off, val);
}
static void
void
at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
{
struct at91_pmc_softc *sc = pmc_softc;
@ -221,6 +183,15 @@ at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
} else {
value = 0;
}
/* Workaround RM9200 Errata #26 */
if (at91_is_rm92() &&
((value ^ RD4(sc, CKGR_PLLBR)) & 0x03f0ff) != 0) {
WR4(sc, CKGR_PLLBR, value ^ 1);
while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
continue;
}
WR4(sc, CKGR_PLLBR, value);
while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
continue;
@ -254,15 +225,75 @@ at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on)
continue;
}
struct at91_pmc_clock *
at91_pmc_clock_add(const char *name, uint32_t irq, struct at91_pmc_clock *parent)
{
struct at91_pmc_clock *clk;
int i, buflen;
clk = malloc(sizeof(*clk), M_PMC, M_NOWAIT | M_ZERO);
if (clk == NULL)
goto err;
buflen = strlen(name) + 1;
clk->name = malloc(buflen, M_PMC, M_NOWAIT);
if (clk->name == NULL)
goto err;
strlcpy(clk->name, name, buflen);
clk->pmc_mask = 1 << irq;
clk->set_mode = &at91_pmc_set_periph_mode;
if (parent == NULL)
clk->parent = &mck;
else
clk->parent = parent;
for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
if (clock_list[i] == NULL) {
clock_list[i] = clk;
return (clk);
}
}
err:
if (clk != NULL) {
if (clk->name != NULL)
free(clk->name, M_PMC);
free(clk, M_PMC);
}
panic("could not allocate pmc clock '%s'", name);
return (NULL);
}
static void
at91_pmc_clock_alias(const char *name, const char *alias)
{
struct at91_pmc_clock *clk, *alias_clk;
clk = at91_pmc_clock_ref(name);
if (clk)
alias_clk = at91_pmc_clock_add(alias, 0, clk->parent);
if (clk && alias_clk) {
alias_clk->hz = clk->hz;
alias_clk->pmc_mask = clk->pmc_mask;
alias_clk->set_mode = clk->set_mode;
}
}
struct at91_pmc_clock *
at91_pmc_clock_ref(const char *name)
{
int i;
for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++)
for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
if (clock_list[i] == NULL)
break;
if (strcmp(name, clock_list[i]->name) == 0)
return (clock_list[i]);
}
//printf("at91_pmc: Warning - did not find clock '%s'", name);
return (NULL);
}
@ -292,55 +323,53 @@ at91_pmc_clock_disable(struct at91_pmc_clock *clk)
}
static int
at91_pmc_pll_rate(int freq, uint32_t reg, int is_pllb)
at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg)
{
uint32_t mul, div;
uint32_t mul, div, freq;;
freq = clk->parent->hz;
div = (reg >> clk->pll_div_shift) & clk->pll_div_mask;
mul = (reg >> clk->pll_mul_shift) & clk->pll_mul_mask;
// printf("pll = (%d / %d) * %d = %d\n",
// freq, div ,mul + 1, (freq/div) * (mul+1));
div = reg & 0xff;
#ifdef AT91SAM9G20
if (is_pllb)
mul = (reg >> 16) & 0x3f;
else
mul = (reg >> 16) & 0xff;
#else
mul = (reg >> 16) & 0x7ff;
#endif
if (div != 0 && mul != 0) {
freq /= div;
freq *= mul + 1;
} else {
freq = 0;
}
#ifndef AT91SAM9G20
if (is_pllb && (reg & (1 << 28)))
freq >>= 1;
#endif
clk->hz = freq;
return (freq);
}
static uint32_t
at91_pmc_pll_calc(uint32_t main_freq, uint32_t out_freq)
at91_pmc_pll_calc(struct at91_pmc_clock *clk, uint32_t out_freq)
{
uint32_t i, div = 0, mul = 0, diff = 1 << 30;
unsigned ret = (out_freq > PMC_PLL_FAST_THRESH) ? 0xbe00 : 0x3e00;
if (out_freq > PMC_PLL_MAX_OUT_FREQ)
unsigned ret = 0x3e00;
if (out_freq > clk->pll_max_out)
goto fail;
for (i = 1; i < 256; i++) {
int32_t diff1;
uint32_t input, mul1;
input = main_freq / i;
if (input < PMC_PLL_MIN_IN_FREQ)
input = clk->parent->hz / i;
if (input < clk->pll_min_in)
break;
if (input > PMC_PLL_MAX_IN_FREQ)
if (input > clk->pll_max_in)
continue;
mul1 = out_freq / input;
if (mul1 > PMC_PLL_MULT_MAX)
if (mul1 > (clk->pll_mul_mask + 1))
continue;
if (mul1 < PMC_PLL_MULT_MIN)
if (mul1 == 0)
break;
diff1 = out_freq - input * mul1;
@ -356,53 +385,94 @@ at91_pmc_pll_calc(uint32_t main_freq, uint32_t out_freq)
}
if (diff > (out_freq >> PMC_PLL_SHIFT_TOL))
goto fail;
return ret | ((mul - 1) << 16) | div;
if (clk->set_outb != NULL)
ret |= clk->set_outb(out_freq);
return (ret |
((mul - 1) << clk->pll_mul_shift) |
(div << clk->pll_div_shift));
fail:
return 0;
return (0);
}
static void
at91_pmc_init_clock(struct at91_pmc_softc *sc, unsigned int main_clock)
{
uint32_t mckr;
int freq;
uint32_t mdiv;
if (at91_is_sam9()) {
uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
udpck.pmc_mask = PMC_SCER_UDP_SAM9;
}
mckr = RD4(sc, PMC_MCKR);
sc->main_clock_hz = main_clock;
main_ck.hz = main_clock;
plla.hz = at91_pmc_pll_rate(main_clock, RD4(sc, CKGR_PLLAR), 0);
at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
if (at91_cpu_is(AT91_CPU_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
plla.hz /= 2;
/*
* Initialize the usb clock. This sets up pllb, but disables the
* actual clock.
*/
sc->pllb_init = at91_pmc_pll_calc(main_clock, 48000000 * 2) |0x10000000;
pllb.hz = at91_pmc_pll_rate(main_clock, sc->pllb_init, 1);
WR4(sc, PMC_PCDR, (1 << IRQ_UHP) | (1 << IRQ_UDP));
WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
WR4(sc, CKGR_PLLBR, 0);
#ifndef AT91SAM9G20
WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
sc->pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000;
at91_pmc_pll_rate(&pllb, sc->pllb_init);
#if 0
/* Turn off USB clocks */
at91_pmc_set_periph_mode(&ohci_clk, 0);
at91_pmc_set_periph_mode(&udc_clk, 0);
#endif
if (at91_is_rm92()) {
WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
} else {
WR4(sc, PMC_SCDR, PMC_SCER_UHP_SAM9 | PMC_SCER_UDP_SAM9);
}
WR4(sc, CKGR_PLLBR, 0);
/*
* MCK and PCU derive from one of the primary clocks. Initialize
* this relationship.
*/
mckr = RD4(sc, PMC_MCKR);
mck.parent = clock_list[mckr & 0x3];
mck.parent->refcnt++;
freq = mck.parent->hz / (1 << ((mckr >> 2) & 3));
mck.hz = freq / (1 + ((mckr >> 8) & 3));
cpu.hz =
mck.hz = mck.parent->hz /
(1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2));
mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8;
if (at91_is_sam9()) {
if (mdiv > 0)
mck.hz /= mdiv * 2;
} else
mck.hz /= (1 + mdiv);
/* Only found on SAM9G20 */
if (at91_cpu_is(AT91_CPU_SAM9G20))
cpu.hz /= (mckr & PMC_MCKR_PDIV) ? 2 : 1;
at91_master_clock = mck.hz;
device_printf(sc->dev,
"Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n",
sc->main_clock_hz,
at91_pmc_pll_rate(main_clock, RD4(sc, CKGR_PLLAR), 0) / 1000000,
freq / 1000000, mck.hz / 1000000);
plla.hz / 1000000,
cpu.hz / 1000000, mck.hz / 1000000);
/* Turn off "Progamable" clocks */
WR4(sc, PMC_SCDR, PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2 |
PMC_SCER_PCK3);
/* XXX kludge, turn on all peripherals */
WR4(sc, PMC_PCER, 0xffffffff);
/* Disable all interrupts for PMC */
WR4(sc, PMC_IDR, 0xffffffff);
}
@ -482,7 +552,7 @@ at91_pmc_attach(device_t dev)
pmc_softc = device_get_softc(dev);
pmc_softc->dev = dev;
if ((err = at91_pmc_activate(dev)) != 0)
return err;
return (err);
/*
* Configure main clock frequency.
@ -493,6 +563,11 @@ at91_pmc_attach(device_t dev)
mainf = AT91C_MAIN_CLOCK;
#endif
at91_pmc_init_clock(pmc_softc, mainf);
/* These clocks refrenced by "special" names */
at91_pmc_clock_alias("ohci0", "ohci_clk");
at91_pmc_clock_alias("udp0", "udp_clk");
return (0);
}

View file

@ -58,21 +58,6 @@
#define PMC_SR 0x68 /* Status Register */
#define PMC_IMR 0x6c /* Interrupt Mask Register */
#ifdef AT91SAM9G20
/* PMC Specific AT91SAM9G20 */
/* PMC System Clock Enable Register */
/* PMC System Clock Disable Register */
/* PMC System Clock StatusRegister */
#define PMC_SCER_UHP (1UL << 6) /* UHP: USB Host Port Clock Enable */
#define PMC_SCER_UDP (1UL << 7) /* UDP: USB Device Port Clock Enable */
#define PMC_SCER_PCK0 (1UL << 8) /* PCK0: Programmable Clock out en */
#define PMC_SCER_PCK1 (1UL << 9) /* PCK1: Programmable Clock out en */
#define PMC_SCER_PCK2 (1UL << 10) /* PCK2: Programmable Clock out en */
#define PMC_SCER_PCK3 (1UL << 11) /* PCK3: Programmable Clock out en */
#else
/* PMC System Clock Enable Register */
/* PMC System Clock Disable Register */
/* PMC System Clock StatusRegister */
@ -81,11 +66,12 @@
#define PMC_SCER_MCKUDP (1UL << 2) /* MCKUDP: Master disable susp/res */
#define PMC_SCER_UHP (1UL << 4) /* UHP: USB Host Port Clock Enable */
#define PMC_SCER_PCK0 (1UL << 8) /* PCK0: Programmable Clock out en */
#define PMC_SCER_PCK1 (1UL << 10) /* PCK1: Programmable Clock out en */
#define PMC_SCER_PCK2 (1UL << 11) /* PCK2: Programmable Clock out en */
#define PMC_SCER_PCK3 (1UL << 12) /* PCK3: Programmable Clock out en */
#define PMC_SCER_PCK1 (1UL << 9) /* PCK1: Programmable Clock out en */
#define PMC_SCER_PCK2 (1UL << 10) /* PCK2: Programmable Clock out en */
#define PMC_SCER_PCK3 (1UL << 11) /* PCK3: Programmable Clock out en */
#define PMC_SCER_UHP_SAM9 (1UL << 6) /* UHP: USB Host Port Clock Enable */
#define PMC_SCER_UDP_SAM9 (1UL << 7) /* UDP: USB Device Port Clock Enable */
#endif /* AT91SAM9G20 */
/* PMC Peripheral Clock Enable Register */
/* PMC Peripheral Clock Disable Register */
/* PMC Peripheral Clock Status Register */
@ -100,6 +86,13 @@
#define CKGR_MCFR_MAINRDY (1UL << 16) /* Main Clock Ready */
#define CKGR_MCFR_MAINF_MASK 0xfffful /* Main Clock Frequency */
/* PMC Clock Generator Master Clock Register */
#define PMC_MCKR_PDIV (1 << 12) /* SAM9G20 Only */
#define PMC_MCKR_PLLADIV2 (1 << 12) /* SAM9G45 Only */
#define PMC_MCKR_CSS_MASK (3 << 0)
#define PMC_MCKR_MDIV_MASK (3 << 8)
#define PMC_MCKR_PRES_MASK (7 << 2)
/* PMC Interrupt Enable Register */
/* PMC Interrupt Disable Register */
/* PMC Status Register */

View file

@ -30,7 +30,7 @@
struct at91_pmc_clock
{
const char *name;
char *name;
uint32_t hz;
struct at91_pmc_clock *parent;
uint32_t pmc_mask;
@ -40,8 +40,23 @@ struct at91_pmc_clock
unsigned primary:1;
unsigned pll:1;
unsigned programmable:1;
/* PLL Params */
uint32_t pll_min_in;
uint32_t pll_max_in;
uint32_t pll_min_out;
uint32_t pll_max_out;
uint32_t pll_div_shift;
uint32_t pll_div_mask;
uint32_t pll_mul_shift;
uint32_t pll_mul_mask;
uint32_t (*set_outb)(int);
};
struct at91_pmc_clock * at91_pmc_clock_add(const char *name, uint32_t irq,
struct at91_pmc_clock *parent);
struct at91_pmc_clock *at91_pmc_clock_ref(const char *name);
void at91_pmc_clock_deref(struct at91_pmc_clock *);
void at91_pmc_clock_enable(struct at91_pmc_clock *);

57
sys/arm/at91/at91_reset.S Normal file
View file

@ -0,0 +1,57 @@
#include <machine/asm.h>
#include <arm/at91/at91_rstreg.h>
#include <arm/at91/at91sam9g20reg.h>
__FBSDID("$FreeBSD$");
#define SDRAM_TR (AT91SAM9G20_BASE + \
AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_TR)
#define SDRAM_LPR (AT91SAM9G20_BASE + \
AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_LPR)
#define RSTC_RCR (AT91SAM9G20_BASE + \
AT91SAM9G20_RSTC_BASE + RST_CR)
/*
* From AT91SAM9G20 Datasheet errata 44:3.5:
*
* When User Reset occurs durring SDRAM read acces, eh SDRAM clock is turned
* off while data are ready to be read on the data bus. The SDRAM maintains
* the data until the clock restarts.
*
* If the User reset is programed to assert a general reset, the data
* If the User reset is programed to assert a general reset, the data
* maintained by the SDRAM leads to a data bus conflict and adversly affects
* the boot memories connected to the EBI:
* + NAND Flash boot functionality, if the system boots out of internal ROM.
* + NOR Flash boot, if the system boots on an external memory connected to
* the EBI CS0.
*
* Assembly code is mandatory for the following sequnce as ARM
* instructions need to be piplined.
*
*/
ENTRY(cpu_reset_sam9g20)
/* Disable IRQs */
mrs r0, cpsr
orr r0, r0, #0x80
msr cpsr_c, r0
/* Change Refresh to block all data access */
ldr r0, =SDRAM_TR
ldr r1, =1
str r1, [r0]
/* Prepare power down command */
ldr r0, =SDRAM_LPR
ldr r1, =2
/* Prepare proc_reset and periph reset */
ldr r2, =RSTC_RCR
ldr r3, =0xA5000005
/* perform power down command */
str r1, [r0]
/* Perfom proc_reset and periph reset (in the ARM pipeline) */
str r3, [r2]

215
sys/arm/at91/at91_rst.c Normal file
View file

@ -0,0 +1,215 @@
/*-
* Copyright (c) 2010 Greg Ansley. 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 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 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/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_rstreg.h>
#include <arm/at91/at91board.h>
#define RST_TIMEOUT (5) /* Seconds to hold NRST for hard reset */
#define RST_TICK (20) /* sample NRST at hz/RST_TICK intervals */
static int rst_intr(void *arg);
static struct rst_softc {
struct resource *mem_res; /* Memory resource */
struct resource *irq_res; /* IRQ resource */
void *intrhand; /* Interrupt handle */
struct callout tick_ch; /* Tick callout */
device_t sc_dev;
u_int shutdown; /* Shutdown in progress */
} *rst_sc;
static inline uint32_t
RD4(struct rst_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->mem_res, off));
}
static inline void
WR4(struct rst_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
static int
at91_rst_probe(device_t dev)
{
if (at91_is_sam9()) {
device_set_desc(dev, "AT91SAM9 Reset Controller");
return (0);
}
return (ENXIO);
}
static int
at91_rst_attach(device_t dev)
{
struct rst_softc *sc;
const char *cause;
int rid, err;
rst_sc = sc = device_get_softc(dev);
sc->sc_dev = dev;
callout_init(&sc->tick_ch, 0);
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL) {
device_printf(dev, "could not allocate memory resources.\n");
err = ENOMEM;
goto out;
}
rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE | RF_SHAREABLE);
if (sc->irq_res == NULL) {
device_printf(dev, "could not allocate interrupt resources.\n");
err = ENOMEM;
goto out;
}
/* Activate the interrupt. */
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
rst_intr, NULL, sc, &sc->intrhand);
if (err)
device_printf(dev, "could not establish interrupt handler.\n");
WR4(rst_sc, RST_MR, RST_MR_ERSTL(0xd) | RST_MR_URSIEN | RST_MR_KEY);
switch (RD4(sc, RST_SR) & RST_SR_RST_MASK) {
case RST_SR_RST_POW:
cause = "Power On";
break;
case RST_SR_RST_WAKE:
cause = "Wake Up";
break;
case RST_SR_RST_WDT:
cause = "Watchdog";
break;
case RST_SR_RST_SOFT:
cause = "Software Request";
break;
case RST_SR_RST_USR:
cause = "External (User)";
break;
default:
cause = "Unknown";
break;
}
device_printf(dev, "Reset cause: %s.\n", cause);
/* cpu_reset_addr = cpu_reset; */
out:
return (err);
}
static void
rst_tick(void *argp)
{
struct rst_softc *sc = argp;
if (sc->shutdown++ >= RST_TIMEOUT * RST_TICK) {
/* User released the button in morre than RST_TIMEOUT */
cpu_reset();
} else if ((RD4(sc, RST_SR) & RST_SR_NRSTL)) {
/* User released the button in less than RST_TIMEOUT */
sc->shutdown = 0;
device_printf(sc->sc_dev, "shutting down...\n");
shutdown_nice(0);
} else {
callout_reset(&sc->tick_ch, hz/RST_TICK, rst_tick, sc);
}
}
static int
rst_intr(void *argp)
{
struct rst_softc *sc = argp;
if (RD4(sc, RST_SR) & RST_SR_URSTS) {
if (sc->shutdown == 0)
callout_reset(&sc->tick_ch, hz/RST_TICK, rst_tick, sc);
return (FILTER_HANDLED);
}
return (FILTER_STRAY);
}
static device_method_t at91_rst_methods[] = {
DEVMETHOD(device_probe, at91_rst_probe),
DEVMETHOD(device_attach, at91_rst_attach),
{0,0},
};
static driver_t at91_rst_driver = {
"at91_rst",
at91_rst_methods,
sizeof(struct rst_softc),
};
static devclass_t at91_rst_devclass;
DRIVER_MODULE(at91_rst, atmelarm, at91_rst_driver, at91_rst_devclass, 0, 0);
void cpu_reset_sam9g20(void) __attribute__((weak));
void cpu_reset_sam9g20(void) {}
void
cpu_reset(void)
{
if (rst_sc) {
cpu_reset_sam9g20(); /* May be null */
WR4(rst_sc, RST_MR,
RST_MR_ERSTL(0xd) | RST_MR_URSTEN | RST_MR_KEY);
WR4(rst_sc, RST_CR,
RST_CR_PROCRST |
RST_CR_PERRST |
RST_CR_EXTRST |
RST_CR_KEY);
}
for(;;) ;
}

View file

@ -0,0 +1,59 @@
/*-
* Copyright (c) 2009 Greg Ansley. 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 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 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 ARM_AT91_AT91RSTREG_H
#define ARM_AT91_AT91RSTREG_H
#define RST_CR 0x0 /* Control Register */
#define RST_SR 0x4 /* Status Register */
#define RST_MR 0x8 /* Mode Register */
/* RST_CR */
#define RST_CR_PROCRST (1<<0)
#define RST_CR_PERRST (1<<2)
#define RST_CR_EXTRST (1<<3)
#define RST_CR_KEY (0xa5<<24)
/* RST_SR */
#define RST_SR_SRCMP (1<<17) /* Software Reset in progress */
#define RST_SR_NRSTL (1<<16) /* NRST pin level at MCK */
#define RST_SR_URSTS (1<<0) /* NRST pin has been active */
#define RST_SR_RST_POW (0<<8) /* General (Power On) reset */
#define RST_SR_RST_WAKE (1<<8) /* Wake-up reset */
#define RST_SR_RST_WDT (2<<8) /* Watchdog reset */
#define RST_SR_RST_SOFT (3<<8) /* Software reset */
#define RST_SR_RST_USR (4<<8) /* User (External) reset */
#define RST_SR_RST_MASK (7<<8) /* User (External) reset */
/* RST_MR */
#define RST_MR_URSTEN (1<<0) /* User reset enable */
#define RST_MR_URSIEN (1<<4) /* User interrupt enable */
#define RST_MR_ERSTL(x) ((x)<<8) /* External reset length */
#define RST_MR_KEY (0xa5<<24)
#endif /* ARM_AT91_AT91RSTREG_H */

View file

@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/bus.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_twireg.h>
#include <arm/at91/at91var.h>
@ -338,7 +337,7 @@ at91_twi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
err = EINVAL;
goto out;
}
if (len == 1)
if (len == 1 && msgs[i].flags & IIC_M_RD)
WR4(sc, TWI_CR, TWI_CR_START | TWI_CR_STOP);
else
WR4(sc, TWI_CR, TWI_CR_START);
@ -348,7 +347,7 @@ at91_twi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
if ((sr = RD4(sc, TWI_SR)) & TWI_SR_RXRDY) {
len--;
*buf++ = RD4(sc, TWI_RHR) & 0xff;
if (len == 0 && msgs[i].len != 1)
if (len == 1)
WR4(sc, TWI_CR, TWI_CR_STOP);
}
}
@ -358,8 +357,6 @@ at91_twi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
}
} else {
while (len--) {
if (len == 0 && msgs[i].len != 1)
WR4(sc, TWI_CR, TWI_CR_STOP);
if ((err = at91_twi_wait(sc, TWI_SR_TXRDY)))
goto out;
WR4(sc, TWI_THR, *buf++);

View file

@ -63,7 +63,10 @@
#define TWI_CWGR_CKDIV(x) ((x) << 16) /* Clock Divider */
#define TWI_CWGR_CHDIV(x) ((x) << 8) /* Clock High Divider */
#define TWI_CWGR_CLDIV(x) ((x) << 0) /* Clock Low Divider */
#define TWI_CWGR_DIV(rate) ((at91_master_clock /(4*(rate))) - 2)
#define TWI_CWGR_DIV(rate) \
(at91_is_sam9() ? \
((at91_master_clock /(4*(rate))) - 3) : \
((at91_master_clock /(4*(rate))) - 2))
/* TWI_SR */
/* TWI_IER */

222
sys/arm/at91/at91_wdt.c Normal file
View file

@ -0,0 +1,222 @@
/*-
* Copyright (c) 2010 Greg Ansley. 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 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 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.
*/
/*
* The sam9 watchdog hardware can be programed only once. So we set the hardware
* watchdog to 16s in wdt_attach and only reset it in the wdt_tick
* handler. The watchdog is halted in processor debug mode.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/watchdog.h>
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_wdtreg.h>
struct wdt_softc {
struct mtx sc_mtx;
device_t sc_dev;
struct resource *mem_res;
struct callout tick_ch;
eventhandler_tag sc_wet;
void *intrhand;
u_int cmd;
u_int interval;
};
static inline uint32_t
RD4(struct wdt_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->mem_res, off));
}
static inline void
WR4(struct wdt_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
}
static int
wdt_intr(void *argp)
{
struct wdt_softc *sc = argp;
if (RD4(sc, WDT_SR) & (WDT_WDUNF | WDT_WDERR)) {
#if defined(KDB) && !defined(KDB_UNATTENDED)
kdb_backtrace();
kdb_enter(KDB_WHY_WATCHDOG, "watchdog timeout");
#else
panic("watchdog timeout");
#endif
}
return (FILTER_STRAY);
}
/* User interface, see watchdog(9) */
static void
wdt_watchdog(void *argp, u_int cmd, int *error)
{
struct wdt_softc *sc = argp;
u_int interval;
mtx_lock(&sc->sc_mtx);
*error = 0;
sc->cmd = 0;
interval = cmd & WD_INTERVAL;
if (interval > WD_TO_16SEC)
*error = EOPNOTSUPP;
else if (interval > 0)
sc->cmd = interval | WD_ACTIVE;
/* We cannot turn of our watchdog so if user
* fails to turn us on go to passive mode. */
if ((sc->cmd & WD_ACTIVE) == 0)
sc->cmd = WD_PASSIVE;
mtx_unlock(&sc->sc_mtx);
}
/* This routine is called no matter what state the user sets the
* watchdog mode to. Called at a rate that is slightly less than
* half the hardware timeout. */
static void
wdt_tick(void *argp)
{
struct wdt_softc *sc = argp;
mtx_assert(&sc->sc_mtx, MA_OWNED);
if (sc->cmd & (WD_ACTIVE | WD_PASSIVE))
WR4(sc, WDT_CR, WDT_KEY|WDT_WDRSTT);
sc->cmd &= WD_PASSIVE;
callout_reset(&sc->tick_ch, sc->interval, wdt_tick, sc);
}
static int
wdt_probe(device_t dev)
{
if (at91_is_sam9()) {
device_set_desc(dev, "WDT");
return (0);
}
return (ENXIO);
}
static int
wdt_attach(device_t dev)
{
static struct wdt_softc *sc;
struct resource *irq;
uint32_t wdt_mr;
int rid, err;
sc = device_get_softc(dev);
sc->cmd = WD_PASSIVE;
sc->sc_dev = dev;
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "at91_wdt", MTX_DEF);
callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->mem_res == NULL)
panic("couldn't allocate wdt register resources");
wdt_mr = RD4(sc, WDT_MR);
if ((wdt_mr & WDT_WDRSTEN) == 0)
device_printf(dev, "Watchdog disabled! (Boot ROM?)\n");
else {
#ifdef WDT_RESET
/* Rude, full reset of whole system on watch dog timeout */
WR4(sc, WDT_MR, WDT_WDDBGHLT | WDT_WDD(0xC00)|
WDT_WDRSTEN| WDT_WDV(0xFFF));
#else
/* Generate stack trace and panic on watchdog timeout*/
WR4(sc, WDT_MR, WDT_WDDBGHLT | WDT_WDD(0xC00)|
WDT_WDFIEN| WDT_WDV(0xFFF));
#endif
/* This may have been set by Boot ROM so register value
* may not be what we just requested since this is a
* write once register. */
wdt_mr = RD4(sc, WDT_MR);
if (wdt_mr & WDT_WDFIEN) {
rid = 0;
irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE | RF_SHAREABLE);
if (!irq)
panic("could not allocate interrupt.\n");
err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, wdt_intr,
NULL, sc, &sc->intrhand);
}
/* interval * hz */
sc->interval = (((wdt_mr & WDT_WDV(~0)) + 1) * WDT_DIV) /
(WDT_CLOCK/hz);
device_printf(dev, "watchdog timeout: %d seconds\n",
sc->interval/hz);
/* Slightly less than 1/2 of watchdog hardware timeout */
sc->interval = (sc->interval/2) - (sc->interval/20);
callout_reset(&sc->tick_ch, sc->interval, wdt_tick, sc);
/* Register us as a watchdog */
sc->sc_wet = EVENTHANDLER_REGISTER(watchdog_list,
wdt_watchdog, sc, 0);
}
return (0);
}
static device_method_t wdt_methods[] = {
DEVMETHOD(device_probe, wdt_probe),
DEVMETHOD(device_attach, wdt_attach),
{0,0},
};
static driver_t wdt_driver = {
"at91_wdt",
wdt_methods,
sizeof(struct wdt_softc),
};
static devclass_t wdt_devclass;
DRIVER_MODULE(at91_wdt, atmelarm, wdt_driver, wdt_devclass, 0, 0);

View file

@ -0,0 +1,60 @@
/*-
* Copyright (c) 2005 Gallon Sylvestre. 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 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 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 ARM_AT91_AT91WDTREG_H
#define ARM_AT91_AT91WDTREG_H
#ifndef WDT_CLOCK
#define WDT_CLOCK (32768)
#endif
#define WDT_DIV (128) /* Clock is slow clock / 128 */
#define WDT_CR 0x0 /* Control Register */
#define WDT_MR 0x4 /* Mode Register */
#define WDT_SR 0x8 /* Status Register */
/* WDT_CR */
#define WDT_KEY (0xa5<<24)
#define WDT_WDRSTT 0x1
/* WDT_MR */
#define WDT_WDV(x) (x & 0xfff) /* counter value*/
#define WDT_WDFIEN (1<<12) /* enable interrupt */
#define WDT_WDRSTEN (1<<13) /* enable reset */
#define WDT_WDRPROC (1<<14) /* processor reset */
#define WDT_WDDIS (1<<15) /* disable */
#define WDT_WDD(x) ((x & 0xfff) << 16) /* delta value */
#define WDT_WDDBGHLT (1<<28) /* halt in debug */
#define WDT_WDIDLEHLT (1<<29) /* halt in idle */
/* WDT_SR */
#define WDT_WDUNF 0x1
#define WDT_WDERR 0x2
#endif /* ARM_AT91_AT91WDTREG_H */

70
sys/arm/at91/at91reg.h Normal file
View file

@ -0,0 +1,70 @@
/*-
* Copyright (c) 2009 Greg Ansley 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 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 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 _AT91REG_H_
#define _AT91REG_H_
#include "opt_at91.h"
/* Where builtin peripherals start in KVM */
#define AT91_BASE 0xd0000000
/* A few things that we count on being the same
* throught the whole family of SOCs */
/* SYSC System Controler */
/* System Registers */
#define AT91_SYS_BASE 0xffff000
#define AT91_SYS_SIZE 0x1000
#if defined(AT91SAM9G45) || defined(AT91SAM9263)
#define AT91_DBGU_BASE 0xfffee00
#else
#define AT91_DBGU_BASE 0xffff200
#endif
#define AT91_DBGU_SIZE 0x200
#define DBGU_C1R (64) /* Chip ID1 Register */
#define DBGU_C2R (68) /* Chip ID2 Register */
#define DBGU_FNTR (72) /* Force NTRST Register */
#define AT91_CPU_VERSION_MASK 0x0000001f
#define AT91_CPU_RM9200 0x09290780
#define AT91_CPU_SAM9260 0x019803a0
#define AT91_CPU_SAM9261 0x019703a0
#define AT91_CPU_SAM9263 0x019607a0
#define AT91_CPU_SAM9G10 0x819903a0
#define AT91_CPU_SAM9G20 0x019905a0
#define AT91_CPU_SAM9G45 0x819b05a0
#define AT91_ARCH(chipid) ((chipid >> 20) & 0xff)
#define AT91_CPU(chipid) (chipid & ~AT91_CPU_VERSION_MASK)
#define AT91_ARCH_SAM9 (0x19)
#define AT91_ARCH_RM92 (0x92)
#endif /* _AT91REG_H_ */

330
sys/arm/at91/at91rm9200.c Normal file
View file

@ -0,0 +1,330 @@
/*-
* Copyright (c) 2005 Olivier Houchard. All rights reserved.
* Copyright (c) 2010 Greg Ansley. 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 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 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/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
struct at91rm92_softc {
device_t dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
bus_space_handle_t sc_sys_sh;
bus_space_handle_t sc_aic_sh;
bus_space_handle_t sc_dbg_sh;
bus_space_handle_t sc_matrix_sh;
};
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
* These values are the ones Atmel uses for its Linux port, which differ
* a little form the ones that are in the standard distribution. Also,
* the ones marked with 'TWEEK' are different based on experience.
*/
static const int at91_irq_prio[32] =
{
7, /* Advanced Interrupt Controller (FIQ) */
7, /* System Peripherals */
1, /* Parallel IO Controller A */
1, /* Parallel IO Controller B */
1, /* Parallel IO Controller C */
1, /* Parallel IO Controller D */
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
5, /* USART 3 */
0, /* Multimedia Card Interface */
2, /* USB Device Port */
4, /* Two-Wire Interface */ /* TWEEK */
5, /* Serial Peripheral Interface */
4, /* Serial Synchronous Controller 0 */
6, /* Serial Synchronous Controller 1 */ /* TWEEK */
4, /* Serial Synchronous Controller 2 */
0, /* Timer Counter 0 */
6, /* Timer Counter 1 */ /* TWEEK */
0, /* Timer Counter 2 */
0, /* Timer Counter 3 */
0, /* Timer Counter 4 */
0, /* Timer Counter 5 */
2, /* USB Host port */
3, /* Ethernet MAC */
0, /* Advanced Interrupt Controller (IRQ0) */
0, /* Advanced Interrupt Controller (IRQ1) */
0, /* Advanced Interrupt Controller (IRQ2) */
0, /* Advanced Interrupt Controller (IRQ3) */
0, /* Advanced Interrupt Controller (IRQ4) */
0, /* Advanced Interrupt Controller (IRQ5) */
0 /* Advanced Interrupt Controller (IRQ6) */
};
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
AT91RM92_ ## _id ##_BASE, \
AT91RM92_ ## _id ## _SIZE, \
AT91RM92_IRQ_ ## _id \
}
static const struct cpu_devs at91_devs[] =
{
DEVICE("at91_pmc", PMC, 0),
DEVICE("at91_st", ST, 0),
DEVICE("at91_pio", PIOA, 0),
DEVICE("at91_pio", PIOB, 1),
DEVICE("at91_pio", PIOC, 2),
DEVICE("at91_pio", PIOD, 3),
DEVICE("at91_rtc", RTC, 0),
DEVICE("at91_mci", MCI, 0),
DEVICE("at91_twi", TWI, 0),
DEVICE("at91_udp", UDP, 0),
DEVICE("ate", EMAC, 0),
DEVICE("at91_ssc", SSC0, 0),
DEVICE("at91_ssc", SSC1, 1),
DEVICE("at91_ssc", SSC2, 2),
DEVICE("spi", SPI, 0),
#ifndef SKYEYE_WORKAROUNDS
DEVICE("uart", DBGU, 0),
DEVICE("uart", USART0, 1),
DEVICE("uart", USART1, 2),
DEVICE("uart", USART2, 3),
DEVICE("uart", USART3, 4),
#else
DEVICE("uart", USART0, 0),
#endif
DEVICE("at91_aic", AIC, 0),
DEVICE("at91_mc", MC, 0),
DEVICE("at91_tc", TC0, 0),
DEVICE("at91_tc", TC1, 1),
DEVICE("ohci", OHCI, 0),
DEVICE("af91_cfata", CF, 0),
{ 0, 0, 0, 0, 0 }
};
static void
at91_add_child(device_t dev, int prio, const char *name, int unit,
bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
{
device_t kid;
struct at91_ivar *ivar;
kid = device_add_child_ordered(dev, prio, name, unit);
if (kid == NULL) {
printf("Can't add child %s%d ordered\n", name, unit);
return;
}
ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
if (ivar == NULL) {
device_delete_child(dev, kid);
printf("Can't add alloc ivar\n");
return;
}
device_set_ivars(kid, ivar);
resource_list_init(&ivar->resources);
if (irq0 != -1) {
bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
if (irq0 != AT91RM92_IRQ_SYSTEM)
at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
}
if (irq1 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
if (irq2 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
if (addr != 0 && addr < AT91RM92_BASE)
addr += AT91RM92_BASE;
if (addr != 0)
bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
}
static void
at91_cpu_add_builtin_children(device_t dev)
{
int i;
const struct cpu_devs *walker;
for (i = 1, walker = at91_devs; walker->name; i++, walker++) {
at91_add_child(dev, i, walker->name, walker->unit,
walker->mem_base, walker->mem_len, walker->irq0,
walker->irq1, walker->irq2);
}
}
static uint32_t
at91_pll_outb(int freq)
{
if (freq > 155000000)
return (0x0000);
else
return (0x8000);
}
static void
at91_identify(driver_t *drv, device_t parent)
{
if (at91_cpu_is(AT91_CPU_RM9200)) {
at91_add_child(parent, 0, "at91rm920", 0, 0, 0, -1, 0, 0);
at91_cpu_add_builtin_children(parent);
}
}
static int
at91_probe(device_t dev)
{
if (at91_cpu_is(AT91_CPU_RM9200)) {
device_set_desc(dev, "AT91RM9200");
return (0);
}
return (ENXIO);
}
static int
at91_attach(device_t dev)
{
struct at91_pmc_clock *clk;
struct at91rm92_softc *sc = device_get_softc(dev);
int i;
struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));
sc->sc_st = at91sc->sc_st;
sc->sc_sh = at91sc->sc_sh;
sc->dev = dev;
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_SYS_BASE,
AT91RM92_SYS_SIZE, &sc->sc_sys_sh) != 0)
panic("Enable to map system registers");
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_DBGU_BASE,
AT91RM92_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
panic("Enable to map DBGU registers");
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_AIC_BASE,
AT91RM92_AIC_SIZE, &sc->sc_aic_sh) != 0)
panic("Enable to map system registers");
/* XXX Hack to tell atmelarm about the AIC */
at91sc->sc_aic_sh = sc->sc_aic_sh;
at91sc->sc_irq_system = AT91RM92_IRQ_SYSTEM;
for (i = 0; i < 32; i++) {
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
i * 4, i);
/* Priority. */
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
at91_irq_prio[i]);
if (i < 8)
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
1);
}
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
/* No debug. */
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
/* Disable and clear all interrupts. */
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
/* Disable all interrupts for RTC (0xe24 == RTC_IDR) */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff);
/* Disable all interrupts for the SDRAM controller */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);
/* Disable all interrupts for DBGU */
bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
/* Update USB device port clock info */
clk = at91_pmc_clock_ref("udpck");
clk->pmc_mask = PMC_SCER_UDP;
at91_pmc_clock_deref(clk);
/* Update USB host port clock info */
clk = at91_pmc_clock_ref("uhpck");
clk->pmc_mask = PMC_SCER_UHP;
at91_pmc_clock_deref(clk);
/* Each SOC has different PLL contraints */
clk = at91_pmc_clock_ref("plla");
clk->pll_min_in = RM9200_PLL_A_MIN_IN_FREQ; /* 1 MHz */
clk->pll_max_in = RM9200_PLL_A_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = RM9200_PLL_A_MIN_OUT_FREQ; /* 80 MHz */
clk->pll_max_out = RM9200_PLL_A_MAX_OUT_FREQ; /* 180 MHz */
clk->pll_mul_shift = RM9200_PLL_A_MUL_SHIFT;
clk->pll_mul_mask = RM9200_PLL_A_MUL_MASK;
clk->pll_div_shift = RM9200_PLL_A_DIV_SHIFT;
clk->pll_div_mask = RM9200_PLL_A_DIV_MASK;
clk->set_outb = at91_pll_outb;
at91_pmc_clock_deref(clk);
clk = at91_pmc_clock_ref("pllb");
clk->pll_min_in = RM9200_PLL_B_MIN_IN_FREQ; /* 100 KHz */
clk->pll_max_in = RM9200_PLL_B_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = RM9200_PLL_B_MIN_OUT_FREQ; /* 30 MHz */
clk->pll_max_out = RM9200_PLL_B_MAX_OUT_FREQ; /* 240 MHz */
clk->pll_mul_shift = RM9200_PLL_B_MUL_SHIFT;
clk->pll_mul_mask = RM9200_PLL_B_MUL_MASK;
clk->pll_div_shift = RM9200_PLL_B_DIV_SHIFT;
clk->pll_div_mask = RM9200_PLL_B_DIV_MASK;
clk->set_outb = at91_pll_outb;
at91_pmc_clock_deref(clk);
return (0);
}
static device_method_t at91_methods[] = {
DEVMETHOD(device_probe, at91_probe),
DEVMETHOD(device_attach, at91_attach),
DEVMETHOD(device_identify, at91_identify),
{0, 0},
};
static driver_t at91rm92_driver = {
"at91rm920",
at91_methods,
sizeof(struct at91rm92_softc),
};
static devclass_t at91rm92_devclass;
DRIVER_MODULE(at91rm920, atmelarm, at91rm92_driver, at91rm92_devclass, 0, 0);

View file

@ -27,6 +27,33 @@
#ifndef AT91RM92REG_H_
#define AT91RM92REG_H_
/* Chip Specific limits */
#define RM9200_PLL_A_MIN_IN_FREQ 1000000 /* 1 MHz */
#define RM9200_PLL_A_MAX_IN_FREQ 32000000 /* 32 MHz */
#define RM9200_PLL_A_MIN_OUT_FREQ 80000000 /* 80 MHz */
#define RM9200_PLL_A_MAX_OUT_FREQ 180000000 /* 180 MHz */
#define RM9200_PLL_A_MUL_SHIFT 16
#define RM9200_PLL_A_MUL_MASK 0x7FF
#define RM9200_PLL_A_DIV_SHIFT 0
#define RM9200_PLL_A_DIV_MASK 0xFF
/*
* PLL B input frequency spec sheet says it must be between 1MHz and 32MHz,
* but it works down as low as 100kHz, a frequency necessary for some
* output frequencies to work.
*
* PLL Max output frequency is 240MHz. The errata says 180MHz is the max
* for some revisions of this part. Be more permissive and optimistic.
*/
#define RM9200_PLL_B_MIN_IN_FREQ 100000 /* 100 KHz */
#define RM9200_PLL_B_MAX_IN_FREQ 32000000 /* 32 MHz */
#define RM9200_PLL_B_MIN_OUT_FREQ 30000000 /* 30 MHz */
#define RM9200_PLL_B_MAX_OUT_FREQ 240000000 /* 240 MHz */
#define RM9200_PLL_B_MUL_SHIFT 16
#define RM9200_PLL_B_MUL_MASK 0x7FF
#define RM9200_PLL_B_DIV_SHIFT 0
#define RM9200_PLL_B_DIV_MASK 0xFF
/*
* Memory map, from datasheet :
* 0x00000000 - 0x0ffffffff : Internal Memories
@ -45,20 +72,26 @@
#define AT91RM92_BASE 0xd0000000
/* Usart */
#define AT91RM92_USART_SIZE 0x4000
#define AT91RM92_USART0_BASE 0xffc0000
#define AT91RM92_USART0_PDC 0xffc0100
#define AT91RM92_USART0_SIZE AT91RM92_USART_SIZE
#define AT91RM92_USART1_BASE 0xffc4000
#define AT91RM92_USART1_PDC 0xffc4100
#define AT91RM92_USART1_SIZE AT91RM92_USART_SIZE
#define AT91RM92_USART2_BASE 0xffc8000
#define AT91RM92_USART2_PDC 0xffc8100
#define AT91RM92_USART2_SIZE AT91RM92_USART_SIZE
#define AT91RM92_USART3_BASE 0xffcc000
#define AT91RM92_USART3_PDC 0xffcc100
#define AT91RM92_USART_SIZE 0x4000
#define AT91RM92_USART3_SIZE AT91RM92_USART_SIZE
/* System Registers */
#define AT91RM92_SYS_BASE 0xffff000
#define AT91RM92_SYS_SIZE 0x1000
#if 0
/* Interrupt Controller */
#define IC_SMR (0) /* Source mode register */
#define IC_SVR (128) /* Source vector register */
@ -79,13 +112,6 @@
#define IC_FFDR (324) /* Fast forcing disable register */
#define IC_FFSR (328) /* Fast forcing status register */
/* DBGU */
#define DBGU 0x200
#define DBGU_SIZE 0x200
#define DBGU_C1R (0x200 + 64) /* Chip ID1 Register */
#define DBGU_C2R (0x200 + 68) /* Chip ID2 Register */
#define DBGU_FNTR (0x200 + 72) /* Force NTRST Register */
#define PIOA_PER (0x400) /* PIO Enable Register */
#define PIOA_PDR (0x400 + 4) /* PIO Disable Register */
@ -204,14 +230,19 @@
#define PIOD_OWDR (0xa00 + 164) /* Output write disable register */
#define PIOD_OWSR (0xa00 + 168) /* Output write status register */
#endif
/*
* PIO
*/
#define AT91RM92_PIOA_BASE 0xffff400
#define AT91RM92_PIO_SIZE 0x200
#define AT91RM92_PIOA_BASE 0xffff400
#define AT91RM92_PIOA_SIZE AT91RM92_PIO_SIZE
#define AT91RM92_PIOB_BASE 0xffff600
#define AT91RM92_PIOB_SIZE AT91RM92_PIO_SIZE
#define AT91RM92_PIOC_BASE 0xffff800
#define AT91RM92_PIOC_SIZE AT91RM92_PIO_SIZE
#define AT91RM92_PIOD_BASE 0xffffa00
#define AT91RM92_PIOD_SIZE AT91RM92_PIO_SIZE
/*
* PMC
@ -271,21 +302,40 @@
#define AT91RM92_IRQ_SSC0 14
#define AT91RM92_IRQ_SSC1 15
#define AT91RM92_IRQ_SSC2 16
#define AT91RM92_IRQ_TC0 17
#define AT91RM92_IRQ_TC1 18
#define AT91RM92_IRQ_TC2 19
#define AT91RM92_IRQ_TC3 20
#define AT91RM92_IRQ_TC4 21
#define AT91RM92_IRQ_TC5 22
#define AT91RM92_IRQ_TC0 17,18,19
#define AT91RM92_IRQ_TC0C0 17
#define AT91RM92_IRQ_TC0C1 18
#define AT91RM92_IRQ_TC0C2 19
#define AT91RM92_IRQ_TC1 20,21,22
#define AT91RM92_IRQ_TC1C1 20
#define AT91RM92_IRQ_TC1C2 21
#define AT91RM92_IRQ_TC1C3 22
#define AT91RM92_IRQ_UHP 23
#define AT91RM92_IRQ_EMAC 24
#define AT91RM92_IRQ_AIC_BASE 25
#define AT91RM92_IRQ_AIC_IRQ0 25
#define AT91RM92_IRQ_AIC_IRQ1 26
#define AT91RM92_IRQ_AIC_IRQ2 27
#define AT91RM92_IRQ_AIC_IRQ3 28
#define AT91RM92_IRQ_AIC_IRQ4 29
#define AT91RM92_IRQ_AIC_IRQ5 30
#define AT91RM92_IRQ_AIC_IRQ6 31
/* Alias */
#define AT91RM92_IRQ_DBGU AT91RM92_IRQ_SYSTEM
#define AT91RM92_IRQ_PMC AT91RM92_IRQ_SYSTEM
#define AT91RM92_IRQ_ST AT91RM92_IRQ_SYSTEM
#define AT91RM92_IRQ_RTC AT91RM92_IRQ_SYSTEM
#define AT91RM92_IRQ_MC AT91RM92_IRQ_SYSTEM
#define AT91RM92_IRQ_OHCI AT91RM92_IRQ_UHP
#define AT91RM92_IRQ_AIC -1
#define AT91RM92_IRQ_CF -1
/* Timer */
#define AT91RM92_AIC_BASE 0xffff000
#define AT91RM92_AIC_SIZE 0x200
/* DBGU */
#define AT91RM92_DBGU_BASE 0xffff200
#define AT91RM92_DBGU_SIZE 0x200
@ -302,16 +352,18 @@
#define AT91RM92_SPI_SIZE 0x4000
#define AT91RM92_SPI_PDC 0xffe0100
#define AT91RM92_SSC_SIZE 0x4000
#define AT91RM92_SSC0_BASE 0xffd0000
#define AT91RM92_SSC0_PDC 0xffd0100
#define AT91RM92_SSC0_SIZE AT91RM92_SSC_SIZE
#define AT91RM92_SSC1_BASE 0xffd4000
#define AT91RM92_SSC1_PDC 0xffd4100
#define AT91RM92_SSC1_SIZE AT91RM92_SSC_SIZE
#define AT91RM92_SSC2_BASE 0xffd8000
#define AT91RM92_SSC2_PDC 0xffd8100
#define AT91RM92_SSC_SIZE 0x4000
#define AT91RM92_SSC2_SIZE AT91RM92_SSC_SIZE
#define AT91RM92_EMAC_BASE 0xffbc000
#define AT91RM92_EMAC_SIZE 0x4000
@ -326,17 +378,23 @@
#define AT91RM92_UDP_BASE 0xffb0000
#define AT91RM92_UDP_SIZE 0x4000
#define AT91RM92_TC0_BASE 0xffa0000
#define AT91RM92_TC_SIZE 0x4000
#define AT91RM92_TC0_BASE 0xffa0000
#define AT91RM92_TC0_SIZE AT91RM92_TC_SIZE
#define AT91RM92_TC0C0_BASE 0xffa0000
#define AT91RM92_TC0C1_BASE 0xffa0040
#define AT91RM92_TC0C2_BASE 0xffa0080
#define AT91RM92_TC1_BASE 0xffa4000
#define AT91RM92_TC1_SIZE AT91RM92_TC_SIZE
#define AT91RM92_TC1C0_BASE 0xffa4000
#define AT91RM92_TC1C1_BASE 0xffa4040
#define AT91RM92_TC1C2_BASE 0xffa4080
/* XXX Needs to be carfully coordinated with
* other * soc's so phyical and vm address
* mapping are unique. XXX
*/
#define AT91RM92_OHCI_BASE 0xdfe00000
#define AT91RM92_OHCI_PA_BASE 0x00300000
#define AT91RM92_OHCI_SIZE 0x00100000

View file

@ -1,717 +0,0 @@
/*-
* Copyright (c) 2005 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 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 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/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/pmap.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91var.h>
static struct at91_softc *at91_softc;
static void at91_eoi(void *);
uint32_t at91_master_clock = AT91C_MASTER_CLOCK;
static int
at91_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
bus_space_handle_t *bshp)
{
vm_paddr_t pa, endpa;
pa = trunc_page(bpa);
if (pa >= 0xfff00000) {
*bshp = pa - 0xf0000000 + 0xd0000000;
return (0);
}
if (pa >= 0xdff00000)
return (0);
endpa = round_page(bpa + size);
*bshp = (vm_offset_t)pmap_mapdev(pa, endpa - pa);
return (0);
}
static void
at91_bs_unmap(void *t, bus_space_handle_t h, bus_size_t size)
{
vm_offset_t va, endva;
va = trunc_page((vm_offset_t)t);
endva = va + round_page(size);
/* Free the kernel virtual mapping. */
kmem_free(kernel_map, va, endva - va);
}
static int
at91_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
bus_size_t size, bus_space_handle_t *nbshp)
{
*nbshp = bsh + offset;
return (0);
}
static void
at91_barrier(void *t, bus_space_handle_t bsh, bus_size_t size, bus_size_t b,
int a)
{
}
bs_protos(generic);
bs_protos(generic_armv4);
struct bus_space at91_bs_tag = {
/* cookie */
(void *) 0,
/* mapping/unmapping */
at91_bs_map,
at91_bs_unmap,
at91_bs_subregion,
/* allocation/deallocation */
NULL,
NULL,
/* barrier */
at91_barrier,
/* read (single) */
generic_bs_r_1,
generic_armv4_bs_r_2,
generic_bs_r_4,
NULL,
/* read multiple */
generic_bs_rm_1,
generic_armv4_bs_rm_2,
generic_bs_rm_4,
NULL,
/* read region */
generic_bs_rr_1,
generic_armv4_bs_rr_2,
generic_bs_rr_4,
NULL,
/* write (single) */
generic_bs_w_1,
generic_armv4_bs_w_2,
generic_bs_w_4,
NULL,
/* write multiple */
generic_bs_wm_1,
generic_armv4_bs_wm_2,
generic_bs_wm_4,
NULL,
/* write region */
NULL,
generic_armv4_bs_wr_2,
generic_bs_wr_4,
NULL,
/* set multiple */
NULL,
NULL,
NULL,
NULL,
/* set region */
NULL,
generic_armv4_bs_sr_2,
generic_bs_sr_4,
NULL,
/* copy */
NULL,
generic_armv4_bs_c_2,
NULL,
NULL,
/* read (single) stream */
generic_bs_r_1,
generic_armv4_bs_r_2,
generic_bs_r_4,
NULL,
/* read multiple stream */
generic_bs_rm_1,
generic_armv4_bs_rm_2,
generic_bs_rm_4,
NULL,
/* read region stream */
generic_bs_rr_1,
generic_armv4_bs_rr_2,
generic_bs_rr_4,
NULL,
/* write (single) stream */
generic_bs_w_1,
generic_armv4_bs_w_2,
generic_bs_w_4,
NULL,
/* write multiple stream */
generic_bs_wm_1,
generic_armv4_bs_wm_2,
generic_bs_wm_4,
NULL,
/* write region stream */
NULL,
generic_armv4_bs_wr_2,
generic_bs_wr_4,
NULL,
};
static int
at91_probe(device_t dev)
{
device_set_desc(dev, "AT91 device bus");
arm_post_filter = at91_eoi;
return (0);
}
static void
at91_identify(driver_t *drv, device_t parent)
{
BUS_ADD_CHILD(parent, 0, "atmelarm", 0);
}
struct arm32_dma_range *
bus_dma_get_range(void)
{
return (NULL);
}
int
bus_dma_get_range_nb(void)
{
return (0);
}
extern void irq_entry(void);
static void
at91_add_child(device_t dev, int prio, const char *name, int unit,
bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
{
device_t kid;
struct at91_ivar *ivar;
kid = device_add_child_ordered(dev, prio, name, unit);
if (kid == NULL) {
printf("Can't add child %s%d ordered\n", name, unit);
return;
}
ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
if (ivar == NULL) {
device_delete_child(dev, kid);
printf("Can't add alloc ivar\n");
return;
}
device_set_ivars(kid, ivar);
resource_list_init(&ivar->resources);
if (irq0 != -1)
bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
if (irq1 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
if (irq2 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
if (addr != 0)
bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
}
struct cpu_devs
{
const char *name;
int unit;
bus_addr_t mem_base;
bus_size_t mem_len;
int irq0;
int irq1;
int irq2;
};
struct cpu_devs at91sam9_devs[] =
{
{
"at91_pit", 0,
AT91SAM9G20_BASE + AT91SAM9G20_PIT_BASE, AT91SAM9G20_PIT_SIZE,
AT91SAM9G20_IRQ_SYSTEM
},
{
"at91_wdt", 0,
AT91SAM9G20_BASE + AT91SAM9G20_WDT_BASE, AT91SAM9G20_WDT_SIZE,
AT91SAM9G20_IRQ_SYSTEM
},
{
"at91_pmc", 0,
AT91SAM9G20_BASE + AT91SAM9G20_PMC_BASE, AT91SAM9G20_PMC_SIZE,
AT91SAM9G20_IRQ_SYSTEM
},
{
"at91_pio", 0,
AT91SAM9G20_BASE + AT91SAM9G20_PIOA_BASE, AT91SAM9G20_PIO_SIZE,
AT91SAM9G20_IRQ_SYSTEM
},
{
"at91_pio", 1,
AT91SAM9G20_BASE + AT91SAM9G20_PIOB_BASE, AT91SAM9G20_PIO_SIZE,
AT91SAM9G20_IRQ_SYSTEM
},
{
"at91_pio", 2,
AT91SAM9G20_BASE + AT91SAM9G20_PIOC_BASE, AT91SAM9G20_PIO_SIZE,
AT91SAM9G20_IRQ_SYSTEM
},
{
"uart", 0,
AT91SAM9G20_BASE + AT91SAM9G20_DBGU_BASE, AT91SAM9G20_DBGU_SIZE,
AT91SAM9G20_IRQ_SYSTEM
},
{
"uart", 1,
AT91SAM9G20_BASE + AT91SAM9G20_USART0_BASE, AT91SAM9G20_USART_SIZE,
AT91SAM9G20_IRQ_USART0
},
{
"uart", 2,
AT91SAM9G20_BASE + AT91SAM9G20_USART1_BASE, AT91SAM9G20_USART_SIZE,
AT91SAM9G20_IRQ_USART1
},
{
"uart", 3,
AT91SAM9G20_BASE + AT91SAM9G20_USART2_BASE, AT91SAM9G20_USART_SIZE,
AT91SAM9G20_IRQ_USART2
},
{
"spi", 0,
AT91SAM9G20_BASE + AT91SAM9G20_SPI0_BASE, AT91SAM9G20_SPI0_SIZE,
AT91SAM9G20_IRQ_SPI0
},
{
"spi", 1,
AT91SAM9G20_BASE + AT91SAM9G20_SPI1_BASE, AT91SAM9G20_SPI1_SIZE,
AT91SAM9G20_IRQ_SPI1
},
{
"ohci", 0,
AT91SAM9G20_OHCI_BASE, AT91SAM9G20_OHCI_SIZE,
AT91SAM9G20_IRQ_UHP
},
{
"macb", 0,
AT91SAM9G20_BASE + AT91SAM9G20_EMAC_BASE, AT91SAM9G20_EMAC_SIZE,
AT91SAM9G20_IRQ_EMAC
},
{
"nand", 0,
AT91SAM9G20_NAND_BASE, AT91SAM9G20_NAND_SIZE,
-1
},
{ 0, 0, 0, 0, 0 }
};
static void
at91_cpu_add_builtin_children(device_t dev, struct at91_softc *sc)
{
int i;
struct cpu_devs *walker;
// XXX should look at the device id in the DBGU register and
// XXX based on the CPU load in these devices
for (i = 0, walker = at91sam9_devs; walker->name; i++, walker++) {
at91_add_child(dev, i, walker->name, walker->unit,
walker->mem_base, walker->mem_len, walker->irq0,
walker->irq1, walker->irq2);
}
}
#define NORMDEV 50
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
* These values are the ones Atmel uses for its Linux port
*/
static int irq_prio[32] =
{
7, /* Advanced Interrupt Controller */
7, /* System Peripherals */
1, /* Parallel IO Controller A */
1, /* Parallel IO Controller B */
1, /* Parallel IO Controller C */
0, /* Analog-to-Digital Converter */
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
0, /* Multimedia Card Interface */
2, /* USB Device Port */
6, /* Two-Wire Interface */
5, /* Serial Peripheral Interface 0 */
5, /* Serial Peripheral Interface 1 */
5, /* Serial Synchronous Controller */
0,
0,
0, /* Timer Counter 0 */
0, /* Timer Counter 1 */
0, /* Timer Counter 2 */
2, /* USB Host port */
3, /* Ethernet */
0, /* Image Sensor Interface */
5, /* USART 3 */
5, /* USART 4 */
5, /* USART 5 */
0, /* Timer Counter 3 */
0, /* Timer Counter 4 */
0, /* Timer Counter 5 */
0, /* Advanced Interrupt Controller */
0, /* Advanced Interrupt Controller */
0, /* Advanced Interrupt Controller */
};
static int
at91_attach(device_t dev)
{
struct at91_softc *sc = device_get_softc(dev);
int i;
at91_softc = sc;
sc->sc_st = &at91_bs_tag;
sc->sc_sh = AT91SAM9G20_BASE;
sc->dev = dev;
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_SYS_BASE,
AT91SAM9G20_SYS_SIZE, &sc->sc_sys_sh) != 0)
panic("Enable to map IRQ registers");
sc->sc_irq_rman.rm_type = RMAN_ARRAY;
sc->sc_irq_rman.rm_descr = "AT91 IRQs";
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "AT91 Memory";
if (rman_init(&sc->sc_irq_rman) != 0 ||
rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0)
panic("at91_attach: failed to set up IRQ rman");
if (rman_init(&sc->sc_mem_rman) != 0 ||
rman_manage_region(&sc->sc_mem_rman, 0xdff00000ul,
0xdffffffful) != 0)
panic("at91_attach: failed to set up memory rman");
if (rman_manage_region(&sc->sc_mem_rman, AT91SAM9G20_OHCI_BASE,
AT91SAM9G20_OHCI_BASE + AT91SAM9G20_OHCI_SIZE - 1) != 0)
panic("at91_attach: failed to set up ohci memory");
if (rman_manage_region(&sc->sc_mem_rman, AT91SAM9G20_NAND_BASE,
AT91SAM9G20_NAND_BASE + AT91SAM9G20_NAND_SIZE - 1) != 0)
panic("at91_attach: failed to set up ohci memory");
#if 0
if (rman_manage_region(&sc->sc_mem_rman, AT91SAM9G20_CF_BASE,
AT91SAM9G20_CF_BASE + AT91SAM9G20_CF_SIZE - 1) != 0)
panic("at91_attach: failed to set up CompactFlash ATA memory");
#endif
for (i = 0; i < 32; i++) {
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_SVR +
i * 4, i);
/* Priority. */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_SMR + i * 4,
irq_prio[i]);
if (i < 8)
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_EOICR,
1);
}
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_SPU, 32);
/* No debug. */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_DCR, 0);
/* Disable and clear all interrupts. */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_IDCR, 0xffffffff);
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_ICCR, 0xffffffff);
/* XXX */
/* Disable all interrupts for RTC (0xe24 == RTC_IDR) */
//bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff);
/* DIsable all interrupts for DBGU */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x120c, 0xffffffff);
/* Disable all interrupts for the SDRAM controller */
//bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);
i = bus_space_read_4(sc->sc_st,
sc->sc_sys_sh, AT91SAM9G20_EBICSA);
/*activate NAND*/
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, AT91SAM9G20_EBICSA,
i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
at91_cpu_add_builtin_children(dev, sc);
bus_generic_probe(dev);
bus_generic_attach(dev);
enable_interrupts(I32_bit | F32_bit);
return (0);
}
static struct resource *
at91_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct at91_softc *sc = device_get_softc(dev);
struct resource_list_entry *rle;
struct at91_ivar *ivar = device_get_ivars(child);
struct resource_list *rl = &ivar->resources;
if (device_get_parent(child) != dev)
return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
type, rid, start, end, count, flags));
rle = resource_list_find(rl, type, *rid);
if (rle == NULL)
return (NULL);
if (rle->res)
panic("Resource rid %d type %d already in use", *rid, type);
if (start == 0UL && end == ~0UL) {
start = rle->start;
count = ulmax(count, rle->count);
end = ulmax(rle->end, start + count - 1);
}
switch (type)
{
case SYS_RES_IRQ:
rle->res = rman_reserve_resource(&sc->sc_irq_rman,
start, end, count, flags, child);
break;
case SYS_RES_MEMORY:
rle->res = rman_reserve_resource(&sc->sc_mem_rman,
start, end, count, flags, child);
if (rle->res != NULL) {
rman_set_bustag(rle->res, &at91_bs_tag);
rman_set_bushandle(rle->res, start);
}
break;
}
if (rle->res) {
rle->start = rman_get_start(rle->res);
rle->end = rman_get_end(rle->res);
rle->count = count;
rman_set_rid(rle->res, *rid);
}
return (rle->res);
}
static struct resource_list *
at91_get_resource_list(device_t dev, device_t child)
{
struct at91_ivar *ivar;
ivar = device_get_ivars(child);
return (&(ivar->resources));
}
static int
at91_release_resource(device_t dev, device_t child, int type,
int rid, struct resource *r)
{
struct resource_list *rl;
struct resource_list_entry *rle;
rl = at91_get_resource_list(dev, child);
if (rl == NULL)
return (EINVAL);
rle = resource_list_find(rl, type, rid);
if (rle == NULL)
return (EINVAL);
rman_release_resource(r);
rle->res = NULL;
return (0);
}
static int
at91_setup_intr(device_t dev, device_t child,
struct resource *ires, int flags, driver_filter_t *filt,
driver_intr_t *intr, void *arg, void **cookiep)
{
struct at91_softc *sc = device_get_softc(dev);
if (rman_get_start(ires) == AT91SAM9G20_IRQ_SYSTEM && filt == NULL)
panic("All system interrupt ISRs must be FILTER");
BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
intr, arg, cookiep);
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_IECR,
1 << rman_get_start(ires));
return (0);
}
static int
at91_teardown_intr(device_t dev, device_t child, struct resource *res,
void *cookie)
{
struct at91_softc *sc = device_get_softc(dev);
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x1000 + IC_IDCR,
1 << rman_get_start(res));
return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
}
static int
at91_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
#if 0
u_long p;
int error;
if (type == SYS_RES_MEMORY) {
error = bus_space_map(rman_get_bustag(r),
rman_get_bushandle(r), rman_get_size(r), 0, &p);
if (error)
return (error);
rman_set_bushandle(r, p);
}
#endif
return (rman_activate_resource(r));
}
static int
at91_print_child(device_t dev, device_t child)
{
struct at91_ivar *ivars;
struct resource_list *rl;
int retval = 0;
ivars = device_get_ivars(child);
rl = &ivars->resources;
retval += bus_print_child_header(dev, child);
retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
if (device_get_flags(dev))
retval += printf(" flags %#x", device_get_flags(dev));
retval += bus_print_child_footer(dev, child);
return (retval);
}
void
arm_mask_irq(uintptr_t nb)
{
bus_space_write_4(at91_softc->sc_st,
at91_softc->sc_sys_sh, 0x1000 + IC_IDCR, 1 << nb);
}
int
arm_get_next_irq(int last __unused)
{
int status;
int irq;
irq = bus_space_read_4(at91_softc->sc_st,
at91_softc->sc_sys_sh, 0x1000 + IC_IVR);
status = bus_space_read_4(at91_softc->sc_st,
at91_softc->sc_sys_sh, 0x1000 + IC_ISR);
if (status == 0) {
bus_space_write_4(at91_softc->sc_st,
at91_softc->sc_sys_sh, 0x1000 + IC_EOICR, 1);
return (-1);
}
return (irq);
}
void
arm_unmask_irq(uintptr_t nb)
{
bus_space_write_4(at91_softc->sc_st,
at91_softc->sc_sys_sh, 0x1000 + IC_IECR, 1 << nb);
bus_space_write_4(at91_softc->sc_st, at91_softc->sc_sys_sh,
0x1000 + IC_EOICR, 0);
}
static void
at91_eoi(void *unused)
{
bus_space_write_4(at91_softc->sc_st, at91_softc->sc_sys_sh,
0x1000 + IC_EOICR, 0);
}
static device_method_t at91_methods[] = {
DEVMETHOD(device_probe, at91_probe),
DEVMETHOD(device_attach, at91_attach),
DEVMETHOD(device_identify, at91_identify),
DEVMETHOD(bus_alloc_resource, at91_alloc_resource),
DEVMETHOD(bus_setup_intr, at91_setup_intr),
DEVMETHOD(bus_teardown_intr, at91_teardown_intr),
DEVMETHOD(bus_activate_resource, at91_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_get_resource_list,at91_get_resource_list),
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_release_resource, at91_release_resource),
DEVMETHOD(bus_print_child, at91_print_child),
{0, 0},
};
static driver_t at91_driver = {
"atmelarm",
at91_methods,
sizeof(struct at91_softc),
};
static devclass_t at91_devclass;
DRIVER_MODULE(atmelarm, nexus, at91_driver, at91_devclass, 0, 0);

343
sys/arm/at91/at91sam9260.c Normal file
View file

@ -0,0 +1,343 @@
/*-
* Copyright (c) 2005 Olivier Houchard. All rights reserved.
* Copyright (c) 2010 Greg Ansley. 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 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 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/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91sam9260reg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
struct at91sam9_softc {
device_t dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
bus_space_handle_t sc_sys_sh;
bus_space_handle_t sc_aic_sh;
bus_space_handle_t sc_dbg_sh;
bus_space_handle_t sc_matrix_sh;
};
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
* These values are the ones Atmel uses for its Linux port
*/
static const int at91_irq_prio[32] =
{
7, /* Advanced Interrupt Controller */
7, /* System Peripherals */
1, /* Parallel IO Controller A */
1, /* Parallel IO Controller B */
1, /* Parallel IO Controller C */
0, /* Analog-to-Digital Converter */
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
0, /* Multimedia Card Interface */
2, /* USB Device Port */
6, /* Two-Wire Interface */
5, /* Serial Peripheral Interface 0 */
5, /* Serial Peripheral Interface 1 */
5, /* Serial Synchronous Controller */
0, /* (reserved) */
0, /* (reserved) */
0, /* Timer Counter 0 */
0, /* Timer Counter 1 */
0, /* Timer Counter 2 */
2, /* USB Host port */
3, /* Ethernet */
0, /* Image Sensor Interface */
5, /* USART 3 */
5, /* USART 4 */
5, /* USART 5 */
0, /* Timer Counter 3 */
0, /* Timer Counter 4 */
0, /* Timer Counter 5 */
0, /* Advanced Interrupt Controller IRQ0 */
0, /* Advanced Interrupt Controller IRQ1 */
0, /* Advanced Interrupt Controller IRQ2 */
};
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
AT91SAM9260_ ## _id ##_BASE, \
AT91SAM9260_ ## _id ## _SIZE, \
AT91SAM9260_IRQ_ ## _id \
}
static const struct cpu_devs at91_devs[] =
{
DEVICE("at91_pmc", PMC, 0),
DEVICE("at91_wdt", WDT, 0),
DEVICE("at91_rst", RSTC, 0),
DEVICE("at91_pit", PIT, 0),
DEVICE("at91_pio", PIOA, 0),
DEVICE("at91_pio", PIOB, 1),
DEVICE("at91_pio", PIOC, 2),
DEVICE("at91_twi", TWI, 0),
DEVICE("at91_mci", MCI, 0),
DEVICE("uart", DBGU, 0),
DEVICE("uart", USART0, 1),
DEVICE("uart", USART1, 2),
DEVICE("uart", USART2, 3),
DEVICE("uart", USART3, 4),
DEVICE("uart", USART4, 5),
DEVICE("uart", USART5, 6),
DEVICE("spi", SPI0, 0),
DEVICE("spi", SPI1, 1),
DEVICE("ate", EMAC, 0),
DEVICE("macb", EMAC, 0),
DEVICE("nand", NAND, 0),
DEVICE("ohci", OHCI, 0),
{ 0, 0, 0, 0, 0 }
};
static void
at91_add_child(device_t dev, int prio, const char *name, int unit,
bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
{
device_t kid;
struct at91_ivar *ivar;
kid = device_add_child_ordered(dev, prio, name, unit);
if (kid == NULL) {
printf("Can't add child %s%d ordered\n", name, unit);
return;
}
ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
if (ivar == NULL) {
device_delete_child(dev, kid);
printf("Can't add alloc ivar\n");
return;
}
device_set_ivars(kid, ivar);
resource_list_init(&ivar->resources);
if (irq0 != -1) {
bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
if (irq0 != AT91SAM9260_IRQ_SYSTEM)
at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
}
if (irq1 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
if (irq2 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
if (addr != 0 && addr < AT91SAM9260_BASE)
addr += AT91SAM9260_BASE;
if (addr != 0)
bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
}
static void
at91_cpu_add_builtin_children(device_t dev)
{
int i;
const struct cpu_devs *walker;
for (i = 1, walker = at91_devs; walker->name; i++, walker++) {
at91_add_child(dev, i, walker->name, walker->unit,
walker->mem_base, walker->mem_len, walker->irq0,
walker->irq1, walker->irq2);
}
}
static uint32_t
at91_pll_outa(int freq)
{
if (freq > 195000000)
return (0x20000000);
else
return (0x20008000);
}
static uint32_t
at91_pll_outb(int freq)
{
return (0x4000);
}
static void
at91_identify(driver_t *drv, device_t parent)
{
if (at91_cpu_is(AT91_CPU_SAM9260)) {
at91_add_child(parent, 0, "at91sam9260", 0, 0, 0, -1, 0, 0);
at91_cpu_add_builtin_children(parent);
}
}
static int
at91_probe(device_t dev)
{
if (at91_cpu_is(AT91_CPU_SAM9260)) {
device_set_desc(dev, "AT91SAM9260");
return (0);
}
return (ENXIO);
}
static int
at91_attach(device_t dev)
{
struct at91_pmc_clock *clk;
struct at91sam9_softc *sc = device_get_softc(dev);
int i;
struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));
sc->sc_st = at91sc->sc_st;
sc->sc_sh = at91sc->sc_sh;
sc->dev = dev;
/*
* XXX These values work for the RM9200, SAM926[01], and SAM9260
* will have to fix this when we want to support anything else. XXX
*/
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_SYS_BASE,
AT91SAM9260_SYS_SIZE, &sc->sc_sys_sh) != 0)
panic("Enable to map system registers");
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_DBGU_BASE,
AT91SAM9260_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
panic("Enable to map DBGU registers");
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_AIC_BASE,
AT91SAM9260_AIC_SIZE, &sc->sc_aic_sh) != 0)
panic("Enable to map system registers");
/* XXX Hack to tell atmelarm about the AIC */
at91sc->sc_aic_sh = sc->sc_aic_sh;
at91sc->sc_irq_system = AT91SAM9260_IRQ_SYSTEM;
for (i = 0; i < 32; i++) {
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
i * 4, i);
/* Priority. */
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
at91_irq_prio[i]);
if (i < 8)
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
1);
}
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
/* No debug. */
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
/* Disable and clear all interrupts. */
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
/* Disable all interrupts for DBGU */
bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
if (bus_space_subregion(sc->sc_st, sc->sc_sh,
AT91SAM9260_MATRIX_BASE, AT91SAM9260_MATRIX_SIZE,
&sc->sc_matrix_sh) != 0)
panic("Enable to map matrix registers");
/* activate NAND*/
i = bus_space_read_4(sc->sc_st, sc->sc_matrix_sh,
AT91SAM9260_EBICSA);
bus_space_write_4(sc->sc_st, sc->sc_matrix_sh,
AT91SAM9260_EBICSA,
i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
/* Update USB device port clock info */
clk = at91_pmc_clock_ref("udpck");
clk->pmc_mask = PMC_SCER_UDP_SAM9;
at91_pmc_clock_deref(clk);
/* Update USB host port clock info */
clk = at91_pmc_clock_ref("uhpck");
clk->pmc_mask = PMC_SCER_UHP_SAM9;
at91_pmc_clock_deref(clk);
/* Each SOC has different PLL contraints */
clk = at91_pmc_clock_ref("plla");
clk->pll_min_in = SAM9260_PLL_A_MIN_IN_FREQ; /* 1 MHz */
clk->pll_max_in = SAM9260_PLL_A_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = SAM9260_PLL_A_MIN_OUT_FREQ; /* 80 MHz */
clk->pll_max_out = SAM9260_PLL_A_MAX_OUT_FREQ; /* 240 MHz */
clk->pll_mul_shift = SAM9260_PLL_A_MUL_SHIFT;
clk->pll_mul_mask = SAM9260_PLL_A_MUL_MASK;
clk->pll_div_shift = SAM9260_PLL_A_DIV_SHIFT;
clk->pll_div_mask = SAM9260_PLL_A_DIV_MASK;
clk->set_outb = at91_pll_outa;
at91_pmc_clock_deref(clk);
/*
* Fudge MAX pll in frequence down below 3.0 Mhz to ensure
* PMC alogrithm choose the divisor that causes the input clock
* to be near the optimal 2 Mhz per datasheet. We know
* we are going to be using this for the USB clock at 96 Mhz.
* Causes no extra frequency deviation for all recomended crystal values.
*/
clk = at91_pmc_clock_ref("pllb");
clk->pll_min_in = SAM9260_PLL_B_MIN_IN_FREQ; /* 1 MHz */
clk->pll_max_in = SAM9260_PLL_B_MAX_IN_FREQ; /* 5 MHz */
clk->pll_max_in = 2999999; /* ~3 MHz */
clk->pll_min_out = SAM9260_PLL_B_MIN_OUT_FREQ; /* 70 MHz */
clk->pll_max_out = SAM9260_PLL_B_MAX_OUT_FREQ; /* 130 MHz */
clk->pll_mul_shift = SAM9260_PLL_B_MUL_SHIFT;
clk->pll_mul_mask = SAM9260_PLL_B_MUL_MASK;
clk->pll_div_shift = SAM9260_PLL_B_DIV_SHIFT;
clk->pll_div_mask = SAM9260_PLL_B_DIV_MASK;
clk->set_outb = at91_pll_outb;
at91_pmc_clock_deref(clk);
return (0);
}
static device_method_t at91sam9260_methods[] = {
DEVMETHOD(device_probe, at91_probe),
DEVMETHOD(device_attach, at91_attach),
DEVMETHOD(device_identify, at91_identify),
{0, 0},
};
static driver_t at91sam9260_driver = {
"at91sam9260",
at91sam9260_methods,
sizeof(struct at91sam9_softc),
};
static devclass_t at91sam9260_devclass;
DRIVER_MODULE(at91sam9260, atmelarm, at91sam9260_driver, at91sam9260_devclass, 0, 0);

View file

@ -0,0 +1,310 @@
/*-
* Copyright (c) 2010 Greg Ansley. 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 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 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 AT91SAM9260REG_H_
#define AT91SAM9260REG_H_
#ifndef AT91SAM9260_MASTER_CLOCK
#define AT91SAM9260_MASTER_CLOCK ((18432000 * 43)/6)
#endif
/* Chip Specific limits */
#define SAM9260_PLL_A_MIN_IN_FREQ 1000000 /* 1 Mhz */
#define SAM9260_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */
#define SAM9260_PLL_A_MIN_OUT_FREQ 80000000 /* 80 Mhz */
#define SAM9260_PLL_A_MAX_OUT_FREQ 240000000 /* 240 Mhz */
#define SAM9260_PLL_A_MUL_SHIFT 16
#define SAM9260_PLL_A_MUL_MASK 0x3FF
#define SAM9260_PLL_A_DIV_SHIFT 0
#define SAM9260_PLL_A_DIV_MASK 0xFF
#define SAM9260_PLL_B_MIN_IN_FREQ 1000000 /* 1 Mhz */
#define SAM9260_PLL_B_MAX_IN_FREQ 5000000 /* 5 Mhz */
#define SAM9260_PLL_B_MIN_OUT_FREQ 70000000 /* 70 Mhz */
#define SAM9260_PLL_B_MAX_OUT_FREQ 130000000 /* 130 Mhz */
#define SAM9260_PLL_B_MUL_SHIFT 16
#define SAM9260_PLL_B_MUL_MASK 0x3FF
#define SAM9260_PLL_B_DIV_SHIFT 0
#define SAM9260_PLL_B_DIV_MASK 0xFF
/*
* Memory map, from datasheet :
* 0x00000000 - 0x0ffffffff : Internal Memories
* 0x10000000 - 0x1ffffffff : Chip Select 0
* 0x20000000 - 0x2ffffffff : Chip Select 1
* 0x30000000 - 0x3ffffffff : Chip Select 2
* 0x40000000 - 0x4ffffffff : Chip Select 3
* 0x50000000 - 0x5ffffffff : Chip Select 4
* 0x60000000 - 0x6ffffffff : Chip Select 5
* 0x70000000 - 0x7ffffffff : Chip Select 6
* 0x80000000 - 0x8ffffffff : Chip Select 7
* 0x90000000 - 0xeffffffff : Undefined (Abort)
* 0xf0000000 - 0xfffffffff : Peripherals
*/
#define AT91_CHIPSELECT_0 0x10000000
#define AT91_CHIPSELECT_1 0x20000000
#define AT91_CHIPSELECT_2 0x30000000
#define AT91_CHIPSELECT_3 0x40000000
#define AT91_CHIPSELECT_4 0x50000000
#define AT91_CHIPSELECT_5 0x60000000
#define AT91_CHIPSELECT_6 0x70000000
#define AT91_CHIPSELECT_7 0x80000000
#define AT91SAM9260_BASE 0xd0000000
#define AT91SAM9260_EMAC_BASE 0xffc4000
#define AT91SAM9260_EMAC_SIZE 0x4000
#define AT91SAM9260_RSTC_BASE 0xffffd00
#define AT91SAM9260_RSTC_SIZE 0x10
#define RSTC_CR 0
#define RSTC_PROCRST (1 << 0)
#define RSTC_PERRST (1 << 2)
#define RSTC_KEY (0xa5 << 24)
/* USART*/
#define AT91SAM9260_USART_SIZE 0x4000
#define AT91SAM9260_USART0_BASE 0xffb0000
#define AT91SAM9260_USART0_PDC 0xffb0100
#define AT91SAM9260_USART0_SIZE AT91SAM9260_USART_SIZE
#define AT91SAM9260_USART1_BASE 0xffb4000
#define AT91SAM9260_USART1_PDC 0xffb4100
#define AT91SAM9260_USART1_SIZE AT91SAM9260_USART_SIZE
#define AT91SAM9260_USART2_BASE 0xffb8000
#define AT91SAM9260_USART2_PDC 0xffb8100
#define AT91SAM9260_USART2_SIZE AT91SAM9260_USART_SIZE
#define AT91SAM9260_USART3_BASE 0xffd0000
#define AT91SAM9260_USART3_PDC 0xffd0100
#define AT91SAM9260_USART3_SIZE AT91SAM9260_USART_SIZE
#define AT91SAM9260_USART4_BASE 0xffd4000
#define AT91SAM9260_USART4_PDC 0xffd4100
#define AT91SAM9260_USART4_SIZE AT91SAM9260_USART_SIZE
#define AT91SAM9260_USART5_BASE 0xffd8000
#define AT91SAM9260_USART5_PDC 0xffd8100
#define AT91SAM9260_USART5_SIZE AT91SAM9260_USART_SIZE
/*TC*/
#define AT91SAM9260_TC0_BASE 0xffa0000
#define AT91SAM9260_TC0_SIZE 0x4000
#define AT91SAM9260_TC0C0_BASE 0xffa0000
#define AT91SAM9260_TC0C1_BASE 0xffa0040
#define AT91SAM9260_TC0C2_BASE 0xffa0080
#define AT91SAM9260_TC1_BASE 0xffdc000
#define AT91SAM9260_TC1_SIZE 0x4000
/*SPI*/
#define AT91SAM9260_SPI0_BASE 0xffc8000
#define AT91SAM9260_SPI0_SIZE 0x4000
#define AT91SAM9260_IRQ_SPI0 12
#define AT91SAM9260_SPI1_BASE 0xffcc000
#define AT91SAM9260_SPI1_SIZE 0x4000
#define AT91SAM9260_IRQ_SPI1 13
/* System Registers */
#define AT91SAM9260_SYS_BASE 0xffff000
#define AT91SAM9260_SYS_SIZE 0x1000
#define AT91SAM9260_MATRIX_BASE 0xfffee00
#define AT91SAM9260_MATRIX_SIZE 0x1000
#define AT91SAM9260_EBICSA 0x011C
#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
#define AT91SAM9260_DBGU_BASE 0xffff200
#define AT91SAM9260_DBGU_SIZE 0x200
/*
* PIO
*/
#define AT91SAM9260_PIOA_BASE 0xffff400
#define AT91SAM9260_PIOA_SIZE 0x200
#define AT91SAM9260_PIOB_BASE 0xffff600
#define AT91SAM9260_PIOB_SIZE 0x200
#define AT91SAM9260_PIOC_BASE 0xffff800
#define AT91SAM9260_PIOC_SIZE 0x200
#define AT91RM92_PMC_BASE 0xffffc00
#define AT91RM92_PMC_SIZE 0x100
/* IRQs : */
/*
* 0: AIC
* 1: System peripheral (System timer, RTC, DBGU)
* 2: PIO Controller A
* 3: PIO Controller B
* 4: PIO Controller C
* 5: ADC
* 6: USART 0
* 7: USART 1
* 8: USART 2
* 9: MMC Interface
* 10: USB device port
* 11: Two-wirte interface
* 12: SPI 0
* 13: SPI 1
* 14: SSC
* 15: - (reserved)
* 16: - (reserved)
* 17: Timer Counter 0
* 18: Timer Counter 1
* 19: Timer Counter 2
* 20: USB Host port
* 21: EMAC
* 22: ISI
* 23: USART 3
* 24: USART 4
* 25: USART 2
* 26: Timer Counter 3
* 27: Timer Counter 4
* 28: Timer Counter 5
* 29: AIC IRQ0
* 30: AIC IRQ1
* 31: AIC IRQ2
*/
#define AT91SAM9260_IRQ_SYSTEM 1
#define AT91SAM9260_IRQ_PIOA 2
#define AT91SAM9260_IRQ_PIOB 3
#define AT91SAM9260_IRQ_PIOC 4
#define AT91SAM9260_IRQ_USART0 6
#define AT91SAM9260_IRQ_USART1 7
#define AT91SAM9260_IRQ_USART2 8
#define AT91SAM9260_IRQ_MCI 9
#define AT91SAM9260_IRQ_UDP 10
#define AT91SAM9260_IRQ_TWI 11
#define AT91SAM9260_IRQ_SPI0 12
#define AT91SAM9260_IRQ_SPI1 13
#define AT91SAM9260_IRQ_SSC0 14
#define AT91SAM9260_IRQ_SSC1 15
#define AT91SAM9260_IRQ_SSC2 16
#define AT91SAM9260_IRQ_TC0 17
#define AT91SAM9260_IRQ_TC1 18
#define AT91SAM9260_IRQ_TC2 19
#define AT91SAM9260_IRQ_UHP 20
#define AT91SAM9260_IRQ_EMAC 21
#define AT91SAM9260_IRQ_USART3 23
#define AT91SAM9260_IRQ_USART4 24
#define AT91SAM9260_IRQ_USART5 25
#define AT91SAM9260_IRQ_AICBASE 29
/* Alias */
#define AT91SAM9260_IRQ_DBGU AT91SAM9260_IRQ_SYSTEM
#define AT91SAM9260_IRQ_PMC AT91SAM9260_IRQ_SYSTEM
#define AT91SAM9260_IRQ_WDT AT91SAM9260_IRQ_SYSTEM
#define AT91SAM9260_IRQ_PIT AT91SAM9260_IRQ_SYSTEM
#define AT91SAM9260_IRQ_RSTC AT91SAM9260_IRQ_SYSTEM
#define AT91SAM9260_IRQ_OHCI AT91SAM9260_IRQ_UHP
#define AT91SAM9260_IRQ_NAND (-1)
#define AT91SAM9260_AIC_BASE 0xffff000
#define AT91SAM9260_AIC_SIZE 0x200
/* Timer */
#define AT91SAM9260_WDT_BASE 0xffffd40
#define AT91SAM9260_WDT_SIZE 0x10
#define AT91SAM9260_PIT_BASE 0xffffd30
#define AT91SAM9260_PIT_SIZE 10
#define AT91SAM9260_SMC_BASE 0xfffec00
#define AT91SAM9260_SMC_SIZE 0x200
#define AT91SAM9260_PMC_BASE 0xffffc00
#define AT91SAM9260_PMC_SIZE 0x100
#define AT91SAM9260_UDP_BASE 0xffa4000
#define AT91SAM9260_UDP_SIZE 0x4000
#define AT91SAM9260_MCI_BASE 0xffa8000
#define AT91SAM9260_MCI_SIZE 0x4000
#define AT91SAM9260_TWI_BASE 0xffaC000
#define AT91SAM9260_TWI_SIZE 0x4000
/* XXX Needs to be carfully coordinated with
* other * soc's so phyical and vm address
* mapping are unique. XXX
*/
#define AT91SAM9260_OHCI_BASE 0xdfc00000
#define AT91SAM9260_OHCI_PA_BASE 0x00500000
#define AT91SAM9260_OHCI_SIZE 0x00100000
#define AT91SAM9260_NAND_BASE 0xe0000000
#define AT91SAM9260_NAND_PA_BASE 0x40000000
#define AT91SAM9260_NAND_SIZE 0x10000000
/* SDRAMC */
#define AT91SAM9260_SDRAMC_BASE 0xfffea00
#define AT91SAM9260_SDRAMC_MR 0x00
#define AT91SAM9260_SDRAMC_MR_MODE_NORMAL 0
#define AT91SAM9260_SDRAMC_MR_MODE_NOP 1
#define AT91SAM9260_SDRAMC_MR_MODE_PRECHARGE 2
#define AT91SAM9260_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3
#define AT91SAM9260_SDRAMC_MR_MODE_REFRESH 4
#define AT91SAM9260_SDRAMC_TR 0x04
#define AT91SAM9260_SDRAMC_CR 0x08
#define AT91SAM9260_SDRAMC_CR_NC_8 0x0
#define AT91SAM9260_SDRAMC_CR_NC_9 0x1
#define AT91SAM9260_SDRAMC_CR_NC_10 0x2
#define AT91SAM9260_SDRAMC_CR_NC_11 0x3
#define AT91SAM9260_SDRAMC_CR_NC_MASK 0x00000003
#define AT91SAM9260_SDRAMC_CR_NR_11 0x0
#define AT91SAM9260_SDRAMC_CR_NR_12 0x4
#define AT91SAM9260_SDRAMC_CR_NR_13 0x8
#define AT91SAM9260_SDRAMC_CR_NR_RES 0xc
#define AT91SAM9260_SDRAMC_CR_NR_MASK 0x0000000c
#define AT91SAM9260_SDRAMC_CR_NB_2 0x00
#define AT91SAM9260_SDRAMC_CR_NB_4 0x10
#define AT91SAM9260_SDRAMC_CR_DBW_16 0x80
#define AT91SAM9260_SDRAMC_CR_NB_MASK 0x00000010
#define AT91SAM9260_SDRAMC_CR_NCAS_MASK 0x00000060
#define AT91SAM9260_SDRAMC_CR_TWR_MASK 0x00000780
#define AT91SAM9260_SDRAMC_CR_TRC_MASK 0x00007800
#define AT91SAM9260_SDRAMC_CR_TRP_MASK 0x00078000
#define AT91SAM9260_SDRAMC_CR_TRCD_MASK 0x00780000
#define AT91SAM9260_SDRAMC_CR_TRAS_MASK 0x07800000
#define AT91SAM9260_SDRAMC_CR_TXSR_MASK 0x78000000
#define AT91SAM9260_SDRAMC_HSR 0x0c
#define AT91SAM9260_SDRAMC_LPR 0x10
#define AT91SAM9260_SDRAMC_IER 0x14
#define AT91SAM9260_SDRAMC_IDR 0x18
#define AT91SAM9260_SDRAMC_IMR 0x1c
#define AT91SAM9260_SDRAMC_ISR 0x20
#define AT91SAM9260_SDRAMC_MDR 0x24
#endif /* AT91SAM9260REG_H_*/

View file

@ -1,420 +0,0 @@
/*-
* 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
*
* machdep.c
*
* Machine dependant functions for kernel setup
*
* This file needs a lot of work.
*
* Created : 17/09/94
*/
#include "opt_msgbuf.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define _ARM32_BUS_DMA_PRIVATE
#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/ktr.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/bus.h>
#include <sys/buf.h>
#include <sys/exec.h>
#include <sys/kdb.h>
#include <sys/msgbuf.h>
#include <machine/reg.h>
#include <machine/cpu.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pager.h>
#include <vm/vm_map.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>
#include <machine/bus.h>
#include <sys/reboot.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_rm9200.h>
#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
#define KERNEL_PT_KERN 1
#define KERNEL_PT_KERN_NUM 22
#define KERNEL_PT_AFKERNEL KERNEL_PT_KERN + KERNEL_PT_KERN_NUM /* L2 table for mapping after kernel */
#define KERNEL_PT_AFKERNEL_NUM 5
/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
#define NUM_KERNEL_PTS (KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
/* Define various stack sizes in pages */
#define IRQ_STACK_SIZE 1
#define ABT_STACK_SIZE 1
#define UND_STACK_SIZE 1
extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
extern void *_end;
extern int *end;
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
/* Physical and virtual addresses for some global pages */
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
vm_offset_t physical_pages;
struct pv_addr systempage;
struct pv_addr msgbufpv;
struct pv_addr irqstack;
struct pv_addr undstack;
struct pv_addr abtstack;
struct pv_addr kernelstack;
static void *boot_arg1;
static void *boot_arg2;
static struct trapframe proc0_tf;
/* Static device mappings. */
static const struct pmap_devmap at91sam9_devmap[] = {
/*
* Map the on-board devices VA == PA so that we can access them
* with the MMU on or off.
*/
{
/*
* This at least maps the interrupt controller, the UART
* and the timer. Other devices should use newbus to
* map their memory anyway.
*/
0xdff00000,
0xfff00000,
0x100000,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/*
* We can't just map the OHCI registers VA == PA, because
* AT91RM92_OHCI_BASE belongs to the userland address space.
* We could just choose a different virtual address, but a better
* solution would probably be to just use pmap_mapdev() to allocate
* KVA, as we don't need the OHCI controller before the vm
* initialization is done. However, the AT91 resource allocation
* system doesn't know how to use pmap_mapdev() yet.
*/
{
/*
* Add the ohci controller, and anything else that might be
* on this chip select for a VA/PA mapping.
*/
AT91SAM9G20_OHCI_BASE,
AT91SAM9G20_OHCI_PA_BASE,
AT91SAM9G20_OHCI_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
{
AT91SAM9G20_NAND_BASE,
AT91SAM9G20_NAND_PA_BASE,
AT91SAM9G20_NAND_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
{
0,
0,
0,
0,
0,
}
};
long
at91_ramsize(void)
{
#if 0
uint32_t *SDRAMC = (uint32_t *)(AT91SAM9G20_BASE + AT91SAM9G20_SDRAMC_BASE);
uint32_t cr, mr;
int banks, rows, cols, bw;
cr = SDRAMC[AT91SAM9G20_SDRAMC_CR / 4];
mr = SDRAMC[AT91SAM9G20_SDRAMC_MR / 4];
bw = (mr & AT91SAM9G20_SDRAMC_MR_DBW_16) ? 1 : 2;
banks = (cr & AT91SAM9G20_SDRAMC_CR_NB_4) ? 2 : 1;
rows = ((cr & AT91SAM9G20_SDRAMC_CR_NR_MASK) >> 2) + 11;
cols = (cr & AT91SAM9G20_SDRAMC_CR_NC_MASK) + 8;
return (1 << (cols + rows + banks + bw));
#endif
return 64*1024*1024;
}
void *
initarm(void *arg, void *arg2)
{
struct pv_addr kernel_l1pt;
struct pv_addr dpcpu;
int loop, i;
u_int l1pagetable;
vm_offset_t freemempos;
vm_offset_t afterkern;
uint32_t memsize;
vm_offset_t lastaddr;
boot_arg1 = arg;
boot_arg2 = arg2;
set_cpufuncs();
lastaddr = fake_preload_metadata();
pcpu_init(pcpup, 0, sizeof(struct pcpu));
PCPU_SET(curthread, &thread0);
freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
/* Define a macro to simplify memory allocation */
#define valloc_pages(var, np) \
alloc_pages((var).pv_va, (np)); \
(var).pv_pa = (var).pv_va + (KERNPHYSADDR - KERNVIRTADDR);
#define alloc_pages(var, np) \
(var) = freemempos; \
freemempos += (np * PAGE_SIZE); \
memset((char *)(var), 0, ((np) * PAGE_SIZE));
while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
freemempos += PAGE_SIZE;
valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
valloc_pages(kernel_pt_table[loop],
L2_TABLE_SIZE / PAGE_SIZE);
} else {
kernel_pt_table[loop].pv_va = freemempos -
(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
L2_TABLE_SIZE_REAL;
kernel_pt_table[loop].pv_pa =
kernel_pt_table[loop].pv_va - KERNVIRTADDR +
KERNPHYSADDR;
}
i++;
}
/*
* Allocate a page for the system page mapped to V0x00000000
* This page will just contain the system vectors and can be
* shared by all processes.
*/
valloc_pages(systempage, 1);
/* Allocate dynamic per-cpu area. */
valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
dpcpu_init((void *)dpcpu.pv_va, 0);
/* Allocate stacks for all modes */
valloc_pages(irqstack, IRQ_STACK_SIZE);
valloc_pages(abtstack, ABT_STACK_SIZE);
valloc_pages(undstack, UND_STACK_SIZE);
valloc_pages(kernelstack, KSTACK_PAGES);
valloc_pages(msgbufpv, round_page(MSGBUF_SIZE) / PAGE_SIZE);
/*
* Now we start construction of the L1 page table
* We start by mapping the L2 page tables into the L1.
* This means that we can replace L1 mappings later on if necessary
*/
l1pagetable = kernel_l1pt.pv_va;
/* Map the L2 pages tables in the L1 page table */
pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
&kernel_pt_table[KERNEL_PT_SYS]);
for (i = 0; i < KERNEL_PT_KERN_NUM; i++)
pmap_link_l2pt(l1pagetable, KERNBASE + i * L1_S_SIZE,
&kernel_pt_table[KERNEL_PT_KERN + i]);
pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR,
(((uint32_t)lastaddr - KERNBASE) + PAGE_SIZE) & ~(PAGE_SIZE - 1),
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
afterkern = round_page((lastaddr + L1_S_SIZE) & ~(L1_S_SIZE - 1));
for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
pmap_link_l2pt(l1pagetable, afterkern + i * L1_S_SIZE,
&kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
}
/* Map the vector page. */
pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
/* Map the DPCPU pages */
pmap_map_chunk(l1pagetable, dpcpu.pv_va, dpcpu.pv_pa, DPCPU_SIZE,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
/* Map the stack pages */
pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
KSTACK_PAGES * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
pmap_map_chunk(l1pagetable, msgbufpv.pv_va, msgbufpv.pv_pa,
MSGBUF_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
}
pmap_devmap_bootstrap(l1pagetable, at91sam9_devmap);
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
cninit();
memsize = board_init();
physmem = memsize / PAGE_SIZE;
/*
* Pages were allocated during the secondary bootstrap for the
* stacks for different CPU modes.
* We must now set the r13 registers in the different CPU modes to
* point to these stacks.
* Since the ARM stacks use STMFD etc. we must set r13 to the top end
* of the stack memory.
*/
cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
set_stackptr(PSR_IRQ32_MODE,
irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
set_stackptr(PSR_ABT32_MODE,
abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
set_stackptr(PSR_UND32_MODE,
undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
/*
* We must now clean the cache again....
* Cleaning may be done by reading new data to displace any
* dirty data in the cache. This will have happened in setttb()
* but since we are boot strapping the addresses used for the read
* may have just been remapped and thus the cache could be out
* of sync. A re-clean after the switch will cure this.
* After booting there are no gross relocations of the kernel thus
* this problem will not occur after initarm().
*/
cpu_idcache_wbinv_all();
/* Set stack for exception handlers */
data_abort_handler_address = (u_int)data_abort_handler;
prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
undefined_handler_address = (u_int)undefinedinstruction_bounce;
undefined_init();
proc_linkup0(&proc0, &thread0);
thread0.td_kstack = kernelstack.pv_va;
thread0.td_pcb = (struct pcb *)
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
thread0.td_pcb->pcb_flags = 0;
thread0.td_frame = &proc0_tf;
pcpup->pc_curpcb = thread0.td_pcb;
arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
pmap_curmaxkvaddr = afterkern + L1_S_SIZE * (KERNEL_PT_KERN_NUM - 1);
/*
* ARM_USE_SMALL_ALLOC uses dump_avail, so it must be filled before
* calling pmap_bootstrap.
*/
dump_avail[0] = PHYSADDR;
dump_avail[1] = PHYSADDR + memsize;
dump_avail[2] = 0;
dump_avail[3] = 0;
pmap_bootstrap(freemempos,
KERNVIRTADDR + 3 * memsize,
&kernel_l1pt);
msgbufp = (void*)msgbufpv.pv_va;
msgbufinit(msgbufp, MSGBUF_SIZE);
mutex_init();
i = 0;
#if PHYSADDR != KERNPHYSADDR
phys_avail[i++] = PHYSADDR;
phys_avail[i++] = KERNPHYSADDR;
#endif
phys_avail[i++] = virtual_avail - KERNVIRTADDR + KERNPHYSADDR;
phys_avail[i++] = PHYSADDR + memsize;
phys_avail[i++] = 0;
phys_avail[i++] = 0;
/* Do basic tuning, hz etc */
init_param1();
init_param2(physmem);
kdb_init();
return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
sizeof(struct pcb)));
}

343
sys/arm/at91/at91sam9g20.c Normal file
View file

@ -0,0 +1,343 @@
/*-
* Copyright (c) 2005 Olivier Houchard. All rights reserved.
* Copyright (c) 2010 Greg Ansley. 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 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 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/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
struct at91sam9_softc {
device_t dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
bus_space_handle_t sc_sys_sh;
bus_space_handle_t sc_aic_sh;
bus_space_handle_t sc_dbg_sh;
bus_space_handle_t sc_matrix_sh;
};
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
* These values are the ones Atmel uses for its Linux port
*/
static const int at91_irq_prio[32] =
{
7, /* Advanced Interrupt Controller */
7, /* System Peripherals */
1, /* Parallel IO Controller A */
1, /* Parallel IO Controller B */
1, /* Parallel IO Controller C */
0, /* Analog-to-Digital Converter */
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
0, /* Multimedia Card Interface */
2, /* USB Device Port */
6, /* Two-Wire Interface */
5, /* Serial Peripheral Interface 0 */
5, /* Serial Peripheral Interface 1 */
5, /* Serial Synchronous Controller */
0, /* (reserved) */
0, /* (reserved) */
0, /* Timer Counter 0 */
0, /* Timer Counter 1 */
0, /* Timer Counter 2 */
2, /* USB Host port */
3, /* Ethernet */
0, /* Image Sensor Interface */
5, /* USART 3 */
5, /* USART 4 */
5, /* USART 5 */
0, /* Timer Counter 3 */
0, /* Timer Counter 4 */
0, /* Timer Counter 5 */
0, /* Advanced Interrupt Controller IRQ0 */
0, /* Advanced Interrupt Controller IRQ1 */
0, /* Advanced Interrupt Controller IRQ2 */
};
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
AT91SAM9G20_ ## _id ##_BASE, \
AT91SAM9G20_ ## _id ## _SIZE, \
AT91SAM9G20_IRQ_ ## _id \
}
static const struct cpu_devs at91_devs[] =
{
DEVICE("at91_pmc", PMC, 0),
DEVICE("at91_wdt", WDT, 0),
DEVICE("at91_rst", RSTC, 0),
DEVICE("at91_pit", PIT, 0),
DEVICE("at91_pio", PIOA, 0),
DEVICE("at91_pio", PIOB, 1),
DEVICE("at91_pio", PIOC, 2),
DEVICE("at91_twi", TWI, 0),
DEVICE("at91_mci", MCI, 0),
DEVICE("uart", DBGU, 0),
DEVICE("uart", USART0, 1),
DEVICE("uart", USART1, 2),
DEVICE("uart", USART2, 3),
DEVICE("uart", USART3, 4),
DEVICE("uart", USART4, 5),
DEVICE("uart", USART5, 6),
DEVICE("spi", SPI0, 0),
DEVICE("spi", SPI1, 1),
DEVICE("ate", EMAC, 0),
DEVICE("macb", EMAC, 0),
DEVICE("nand", NAND, 0),
DEVICE("ohci", OHCI, 0),
{ 0, 0, 0, 0, 0 }
};
static void
at91_add_child(device_t dev, int prio, const char *name, int unit,
bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
{
device_t kid;
struct at91_ivar *ivar;
kid = device_add_child_ordered(dev, prio, name, unit);
if (kid == NULL) {
printf("Can't add child %s%d ordered\n", name, unit);
return;
}
ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
if (ivar == NULL) {
device_delete_child(dev, kid);
printf("Can't add alloc ivar\n");
return;
}
device_set_ivars(kid, ivar);
resource_list_init(&ivar->resources);
if (irq0 != -1) {
bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
if (irq0 != AT91SAM9G20_IRQ_SYSTEM)
at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
}
if (irq1 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
if (irq2 != 0)
bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
if (addr != 0 && addr < AT91SAM9G20_BASE)
addr += AT91SAM9G20_BASE;
if (addr != 0)
bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
}
static void
at91_cpu_add_builtin_children(device_t dev)
{
int i;
const struct cpu_devs *walker;
for (i = 1, walker = at91_devs; walker->name; i++, walker++) {
at91_add_child(dev, i, walker->name, walker->unit,
walker->mem_base, walker->mem_len, walker->irq0,
walker->irq1, walker->irq2);
}
}
static uint32_t
at91_pll_outa(int freq)
{
switch (freq / 10000000) {
case 747 ... 801: return ((1 << 29) | (0 << 14));
case 697 ... 746: return ((1 << 29) | (1 << 14));
case 647 ... 696: return ((1 << 29) | (2 << 14));
case 597 ... 646: return ((1 << 29) | (3 << 14));
case 547 ... 596: return ((1 << 29) | (1 << 14));
case 497 ... 546: return ((1 << 29) | (2 << 14));
case 447 ... 496: return ((1 << 29) | (3 << 14));
case 397 ... 446: return ((1 << 29) | (4 << 14));
default: return (1 << 29);
}
}
static uint32_t
at91_pll_outb(int freq)
{
return (0);
}
static void
at91_identify(driver_t *drv, device_t parent)
{
if (at91_cpu_is(AT91_CPU_SAM9G20)) {
at91_add_child(parent, 0, "at91sam", 9, 0, 0, -1, 0, 0);
at91_cpu_add_builtin_children(parent);
}
}
static int
at91_probe(device_t dev)
{
if (at91_cpu_is(AT91_CPU_SAM9G20)) {
device_set_desc(dev, "AT91SAM9G20");
return (0);
}
return (ENXIO);
}
static int
at91_attach(device_t dev)
{
struct at91_pmc_clock *clk;
struct at91sam9_softc *sc = device_get_softc(dev);
int i;
struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));
sc->sc_st = at91sc->sc_st;
sc->sc_sh = at91sc->sc_sh;
sc->dev = dev;
/*
* XXX These values work for the RM9200, SAM926[01], and SAM9G20
* will have to fix this when we want to support anything else. XXX
*/
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_SYS_BASE,
AT91SAM9G20_SYS_SIZE, &sc->sc_sys_sh) != 0)
panic("Enable to map system registers");
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_DBGU_BASE,
AT91SAM9G20_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
panic("Enable to map DBGU registers");
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_AIC_BASE,
AT91SAM9G20_AIC_SIZE, &sc->sc_aic_sh) != 0)
panic("Enable to map system registers");
/* XXX Hack to tell atmelarm about the AIC */
at91sc->sc_aic_sh = sc->sc_aic_sh;
at91sc->sc_irq_system = AT91SAM9G20_IRQ_SYSTEM;
for (i = 0; i < 32; i++) {
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
i * 4, i);
/* Priority. */
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
at91_irq_prio[i]);
if (i < 8)
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
1);
}
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
/* No debug. */
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
/* Disable and clear all interrupts. */
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
/* Disable all interrupts for DBGU */
bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
if (bus_space_subregion(sc->sc_st, sc->sc_sh,
AT91SAM9G20_MATRIX_BASE, AT91SAM9G20_MATRIX_SIZE,
&sc->sc_matrix_sh) != 0)
panic("Enable to map matrix registers");
/* activate NAND*/
i = bus_space_read_4(sc->sc_st, sc->sc_matrix_sh,
AT91SAM9G20_EBICSA);
bus_space_write_4(sc->sc_st, sc->sc_matrix_sh,
AT91SAM9G20_EBICSA,
i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
/* Update USB device port clock info */
clk = at91_pmc_clock_ref("udpck");
clk->pmc_mask = PMC_SCER_UDP_SAM9;
at91_pmc_clock_deref(clk);
/* Update USB host port clock info */
clk = at91_pmc_clock_ref("uhpck");
clk->pmc_mask = PMC_SCER_UHP_SAM9;
at91_pmc_clock_deref(clk);
/* Each SOC has different PLL contraints */
clk = at91_pmc_clock_ref("plla");
clk->pll_min_in = SAM9G20_PLL_A_MIN_IN_FREQ; /* 2 MHz */
clk->pll_max_in = SAM9G20_PLL_A_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = SAM9G20_PLL_A_MIN_OUT_FREQ; /* 400 MHz */
clk->pll_max_out = SAM9G20_PLL_A_MAX_OUT_FREQ; /* 800 MHz */
clk->pll_mul_shift = SAM9G20_PLL_A_MUL_SHIFT;
clk->pll_mul_mask = SAM9G20_PLL_A_MUL_MASK;
clk->pll_div_shift = SAM9G20_PLL_A_DIV_SHIFT;
clk->pll_div_mask = SAM9G20_PLL_A_DIV_MASK;
clk->set_outb = at91_pll_outa;
at91_pmc_clock_deref(clk);
clk = at91_pmc_clock_ref("pllb");
clk->pll_min_in = SAM9G20_PLL_B_MIN_IN_FREQ; /* 2 MHz */
clk->pll_max_in = SAM9G20_PLL_B_MAX_IN_FREQ; /* 32 MHz */
clk->pll_min_out = SAM9G20_PLL_B_MIN_OUT_FREQ; /* 30 MHz */
clk->pll_max_out = SAM9G20_PLL_B_MAX_OUT_FREQ; /* 100 MHz */
clk->pll_mul_shift = SAM9G20_PLL_B_MUL_SHIFT;
clk->pll_mul_mask = SAM9G20_PLL_B_MUL_MASK;
clk->pll_div_shift = SAM9G20_PLL_B_DIV_SHIFT;
clk->pll_div_mask = SAM9G20_PLL_B_DIV_MASK;
clk->set_outb = at91_pll_outb;
at91_pmc_clock_deref(clk);
return (0);
}
static device_method_t at91_methods[] = {
DEVMETHOD(device_probe, at91_probe),
DEVMETHOD(device_attach, at91_attach),
DEVMETHOD(device_identify, at91_identify),
{0, 0},
};
static driver_t at91sam9_driver = {
"at91sam",
at91_methods,
sizeof(struct at91sam9_softc),
};
static devclass_t at91sam9_devclass;
DRIVER_MODULE(at91sam, atmelarm, at91sam9_driver, at91sam9_devclass, 0, 0);

View file

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
* Copyright (c) 2010 Greg Ansley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -28,6 +29,29 @@
#ifndef AT91SAM9G20REG_H_
#define AT91SAM9G20REG_H_
#ifndef AT91SAM9G20_MASTER_CLOCK
#define AT91SAM9G20_MASTER_CLOCK ((18432000 * 43)/6)
#endif
/* Chip Specific limits */
#define SAM9G20_PLL_A_MIN_IN_FREQ 2000000 /* 2 Mhz */
#define SAM9G20_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */
#define SAM9G20_PLL_A_MIN_OUT_FREQ 400000000 /* 400 Mhz */
#define SAM9G20_PLL_A_MAX_OUT_FREQ 800000000 /* 800 Mhz */
#define SAM9G20_PLL_A_MUL_SHIFT 16
#define SAM9G20_PLL_A_MUL_MASK 0xFF
#define SAM9G20_PLL_A_DIV_SHIFT 0
#define SAM9G20_PLL_A_DIV_MASK 0xFF
#define SAM9G20_PLL_B_MIN_IN_FREQ 2000000 /* 2 Mhz */
#define SAM9G20_PLL_B_MAX_IN_FREQ 32000000 /* 32 Mhz */
#define SAM9G20_PLL_B_MIN_OUT_FREQ 30000000 /* 30 Mhz */
#define SAM9G20_PLL_B_MAX_OUT_FREQ 100000000 /* 100 Mhz */
#define SAM9G20_PLL_B_MUL_SHIFT 16
#define SAM9G20_PLL_B_MUL_MASK 0x3F
#define SAM9G20_PLL_B_DIV_SHIFT 0
#define SAM9G20_PLL_B_DIV_MASK 0xFF
/*
* Memory map, from datasheet :
* 0x00000000 - 0x0ffffffff : Internal Memories
@ -56,11 +80,11 @@
#define AT91SAM9G20_BASE 0xd0000000
#define AT91SAM9G20_IRQ_EMAC 21
#define AT91SAM9G20_EMAC_BASE 0xffc4000
#define AT91SAM9G20_EMAC_SIZE 0x4000
#define AT91SAM9G20_RSTC_BASE 0xffffd00
#define AT91SAM9G20_RSTC_SIZE 0x10
#define RSTC_CR 0
#define RSTC_PROCRST (1 << 0)
@ -69,13 +93,25 @@
/* USART*/
#define AT91SAM9G20_USART_SIZE 0x4000
#define AT91SAM9G20_USART0_BASE 0xffb0000
#define AT91SAM9G20_USART0_PDC 0xffb0100
#define AT91SAM9G20_USART0_SIZE AT91SAM9G20_USART_SIZE
#define AT91SAM9G20_USART1_BASE 0xffb4000
#define AT91SAM9G20_USART1_PDC 0xffb4100
#define AT91SAM9G20_USART1_SIZE AT91SAM9G20_USART_SIZE
#define AT91SAM9G20_USART2_BASE 0xffb8000
#define AT91SAM9G20_USART2_PDC 0xffb8100
#define AT91SAM9G20_USART_SIZE 0x4000
#define AT91SAM9G20_USART2_SIZE AT91SAM9G20_USART_SIZE
#define AT91SAM9G20_USART3_BASE 0xffd0000
#define AT91SAM9G20_USART3_PDC 0xffd0100
#define AT91SAM9G20_USART3_SIZE AT91SAM9G20_USART_SIZE
#define AT91SAM9G20_USART4_BASE 0xffd4000
#define AT91SAM9G20_USART4_PDC 0xffd4100
#define AT91SAM9G20_USART4_SIZE AT91SAM9G20_USART_SIZE
#define AT91SAM9G20_USART5_BASE 0xffd8000
#define AT91SAM9G20_USART5_PDC 0xffd8100
#define AT91SAM9G20_USART5_SIZE AT91SAM9G20_USART_SIZE
/*TC*/
#define AT91SAM9G20_TC0_BASE 0xffa0000
@ -99,28 +135,27 @@
#define AT91SAM9G20_IRQ_SPI1 13
/* System Registers */
#define AT91SAM9G20_SYS_BASE 0xfffe000
#define AT91SAM9G20_SYS_SIZE 0x2000
#define AT91SAM9G20_SYS_BASE 0xffff000
#define AT91SAM9G20_SYS_SIZE 0x1000
#define AT91SAM9G20_MATRIX (0xe00)
#define AT91SAM9G20_EBICSA (AT91SAM9G20_MATRIX + 0x011C)
#define AT91SAM9G20_MATRIX_BASE 0xfffee00
#define AT91SAM9G20_MATRIX_SIZE 0x1000
#define AT91SAM9G20_EBICSA 0x011C
#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
#define DBGU 0x200
#define DBGU_SIZE 0x200
#define DBGU_C1R (0x200 + 64) /* Chip ID1 Register */
#define DBGU_C2R (0x200 + 68) /* Chip ID2 Register */
#define DBGU_FNTR (0x200 + 72) /* Force NTRST Register */
#define AT91SAM9G20_DBGU_BASE 0xffff200
#define AT91SAM9G20_DBGU_SIZE 0x200
/*
* PIO
*/
#define AT91SAM9G20_PIOA_BASE 0xffff400
#define AT91SAM9G20_PIO_SIZE 0x200
#define AT91SAM9G20_PIOA_SIZE 0x200
#define AT91SAM9G20_PIOB_BASE 0xffff600
#define AT91SAM9G20_PIOB_SIZE 0x200
#define AT91SAM9G20_PIOC_BASE 0xffff800
#define AT91SAM9G20_PIOC_SIZE 0x200
#define AT91RM92_PMC_BASE 0xffffc00
#define AT91RM92_PMC_SIZE 0x100
@ -131,27 +166,33 @@
* 2: PIO Controller A
* 3: PIO Controller B
* 4: PIO Controller C
* 5: -
* 5: ADC
* 6: USART 0
* 7: USART 1
* 8: USART 2
* 9: MMC Interface
* 10: USB device port
* 11: Two-wirte interface
* 12: SPI
* 13: SPI
* 12: SPI 0
* 13: SPI 1
* 14: SSC
* 15: SSC
* 16: SSC
* 15: - (reserved)
* 16: - (reserved)
* 17: Timer Counter 0
* 18: Timer Counter 1
* 19: Timer Counter 2
* 20: USB Host port
* 21: EMAC
* 22-28: -
* 29: AIC
* 30: AIC
* 31: AIC
* 22: ISI
* 23: USART 3
* 24: USART 4
* 25: USART 2
* 26: Timer Counter 3
* 27: Timer Counter 4
* 28: Timer Counter 5
* 29: AIC IRQ0
* 30: AIC IRQ1
* 31: AIC IRQ2
*/
#define AT91SAM9G20_IRQ_SYSTEM 1
@ -173,12 +214,25 @@
#define AT91SAM9G20_IRQ_TC1 18
#define AT91SAM9G20_IRQ_TC2 19
#define AT91SAM9G20_IRQ_UHP 20
#define AT91SAM9G20_IRQ_EMAC 21
#define AT91SAM9G20_IRQ_USART3 23
#define AT91SAM9G20_IRQ_USART4 24
#define AT91SAM9G20_IRQ_USART5 25
#define AT91SAM9G20_IRQ_AICBASE 29
/* Timer */
/* Alias */
#define AT91SAM9G20_IRQ_DBGU AT91SAM9G20_IRQ_SYSTEM
#define AT91SAM9G20_IRQ_PMC AT91SAM9G20_IRQ_SYSTEM
#define AT91SAM9G20_IRQ_WDT AT91SAM9G20_IRQ_SYSTEM
#define AT91SAM9G20_IRQ_PIT AT91SAM9G20_IRQ_SYSTEM
#define AT91SAM9G20_IRQ_RSTC AT91SAM9G20_IRQ_SYSTEM
#define AT91SAM9G20_IRQ_OHCI AT91SAM9G20_IRQ_UHP
#define AT91SAM9G20_IRQ_NAND (-1)
#define AT91SAM9G20_DBGU_BASE 0xffff200
#define AT91SAM9G20_DBGU_SIZE 0x200
#define AT91SAM9G20_AIC_BASE 0xffff000
#define AT91SAM9G20_AIC_SIZE 0x200
/* Timer */
#define AT91SAM9G20_WDT_BASE 0xffffd40
#define AT91SAM9G20_WDT_SIZE 0x10
@ -195,22 +249,24 @@
#define AT91SAM9G20_UDP_BASE 0xffa4000
#define AT91SAM9G20_UDP_SIZE 0x4000
#define AT91SAM9G20_OHCI_BASE 0xdfe00000
#define AT91SAM9G20_OHCI_PA_BASE 0x00500000
#define AT91SAM9G20_OHCI_SIZE 0x00100000
#define AT91SAM9G20_MCI_BASE 0xffa8000
#define AT91SAM9G20_MCI_SIZE 0x4000
#define AT91SAM9G20_TWI_BASE 0xffaC000
#define AT91SAM9G20_TWI_SIZE 0x4000
//#define AT91SAM9G20_NAND_BASE 0xdf100000
/* XXX Needs to be carfully coordinated with
* other * soc's so phyical and vm address
* mapping are unique. XXX
*/
#define AT91SAM9G20_OHCI_BASE 0xdfc00000
#define AT91SAM9G20_OHCI_PA_BASE 0x00500000
#define AT91SAM9G20_OHCI_SIZE 0x00100000
//#define AT91SAM9G20_NAND_BASE 0x40000000
#define AT91SAM9G20_NAND_BASE 0xe0000000
#define AT91SAM9G20_NAND_PA_BASE 0x40000000
#define AT91SAM9G20_NAND_SIZE 0x10000000
#define AT91SAM9G20_NAND_BASE 0xe0000000
#define AT91SAM9G20_NAND_PA_BASE 0x40000000
#define AT91SAM9G20_NAND_SIZE 0x10000000
//#define AT91SAM9G20_NAND_SIZE 0x00900000
//#define AT91SAM9G20_OHCI_SIZE 0x0004000
/* SDRAMC */
#define AT91SAM9G20_SDRAMC_BASE 0xfffea00
@ -234,6 +290,7 @@
#define AT91SAM9G20_SDRAMC_CR_NR_MASK 0x0000000c
#define AT91SAM9G20_SDRAMC_CR_NB_2 0x00
#define AT91SAM9G20_SDRAMC_CR_NB_4 0x10
#define AT91SAM9G20_SDRAMC_CR_DBW_16 0x80
#define AT91SAM9G20_SDRAMC_CR_NB_MASK 0x00000010
#define AT91SAM9G20_SDRAMC_CR_NCAS_MASK 0x00000060
#define AT91SAM9G20_SDRAMC_CR_TWR_MASK 0x00000780

View file

@ -28,21 +28,62 @@
#ifndef _AT91VAR_H_
#define _AT91VAR_H_
#include <sys/bus.h>
#include <sys/rman.h>
#include <arm/at91/at91reg.h>
struct at91_softc {
device_t dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
bus_space_handle_t sc_sys_sh;
bus_space_handle_t sc_aic_sh;
struct rman sc_irq_rman;
struct rman sc_mem_rman;
uint32_t sc_irq_system;
};
struct at91_ivar {
struct resource_list resources;
};
struct cpu_devs
{
const char *name;
int unit;
bus_addr_t mem_base;
bus_size_t mem_len;
int irq0;
int irq1;
int irq2;
const char *parent_clk;
};
extern uint32_t at91_chip_id;
static inline int at91_is_rm92(void);
static inline int at91_is_sam9(void) ;
static inline int at91_cpu_is(u_int cpu);
static inline int
at91_is_rm92(void)
{
return (AT91_ARCH(at91_chip_id) == AT91_ARCH_RM92);
}
static inline int
at91_is_sam9(void)
{
return (AT91_ARCH(at91_chip_id) == AT91_ARCH_SAM9);
}
static inline int
at91_cpu_is(u_int cpu)
{
return (AT91_CPU(at91_chip_id) == cpu);
}
extern uint32_t at91_irq_system;
extern uint32_t at91_master_clock;
#endif /* _AT91VAR_H_ */

View file

@ -32,11 +32,36 @@ __FBSDID("$FreeBSD$");
#include <arm/at91/at91board.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_sam9.h>
#include <arm/at91/at91_pio_sam9g20.h>
long
board_init(void)
{
/* Setup Ethernet Pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, 1<<7, 0);
at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE, 1<<7);
at91_pio_gpio_set_deglitch(AT91SAM9G20_PIOA_BASE, 1<<7, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA19, 0); /* ETXCK_EREFCK */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA17, 0); /* ERXDV */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA14, 0); /* ERX0 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA15, 0); /* ERX1 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA18, 0); /* ERXER */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA16, 0); /* ETXEN */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA12, 0); /* ETX0 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA13, 0); /* ETX1 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA21, 0); /* EMDIO */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA20, 0); /* EMDC */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA28, 0); /* ECRS */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA29, 0); /* ECOL */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA25, 0); /* ERX2 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA26, 0); /* ERX3 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA27, 0); /* ERXCK */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA23, 0); /* ETX2 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA24, 0); /* ETX3 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA22, 0); /* ETXER */
return (at91_ramsize());
}

View file

@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_piovar.h>
@ -59,5 +60,13 @@ board_init(void)
at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PB21_RXD1, 0);
at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PB20_TXD1, 1);
/* MMC/SD Interface */
at91_pio_use_periph_a(AT91RM92_PIOA_BASE,AT91C_PA27_MCCK, 0);
at91_pio_use_periph_a(AT91RM92_PIOA_BASE,AT91C_PA28_MCCDA, 1);
at91_pio_use_periph_a(AT91RM92_PIOA_BASE,AT91C_PA29_MCDA0, 1);
at91_pio_use_periph_b(AT91RM92_PIOB_BASE,AT91C_PB3_MCDA1, 1);
at91_pio_use_periph_b(AT91RM92_PIOB_BASE,AT91C_PB4_MCDA2, 1);
at91_pio_use_periph_b(AT91RM92_PIOB_BASE,AT91C_PB5_MCDA3, 1);
return (at91_ramsize());
}

View file

@ -0,0 +1,105 @@
/*-
* Copyright (c) 2009 Greg Ansley. 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 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 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.
*/
/* Calao Systems QIL-9G20-Cxx
* http://www.calao-systems.com
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_sam9g20.h>
//#include <arm/at91/at91_led.h>
#define AT91SAM9G20_LED_BASE AT91SAM9G20_PIOA_BASE
#define AT91SAM9G20_LED_SIZE AT91SAM9G20_PIO_SIZE
#define AT91SAM9G20_IRQ_LED AT91SAM9G20_IRQ_PIOA
long
board_init(void)
{
//at91_led_create("power", 0, 9, 0);
/* PIOB's A periph: Turn USART 0's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1);
/* PIOB's A periph: Turn USART 0's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0);
/* PIOB's A periph: Turn USART 1's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0);
/* TWI Two-wire Serial Data */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1);
/* Multimedia Card */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA6_MCDA0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA7_MCCDA, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA9_MCDA1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA10_MCDA2, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA11_MCDA3, 1);
/* SPI0 to DataFlash */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA0_SPI0_MISO, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA1_SPI0_MOSI, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA2_SPI0_SPCK, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA3_SPI0_NPCS0, 0);
/* EMAC */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 , 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER, 0);
return (at91_ramsize());
}

View file

@ -0,0 +1,128 @@
/*-
* Copyright (c) 2009 Greg Ansley. 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 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 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.
*/
/*
* This board file can be used for both:
* Atmel AT91SAM9260-B Development Card and
* Atmel AT91SAM9G20-EK Rev. B Development Card
*
* Since the AT91SAM9260 and AT91SAM9G20 have identical memory maps and
* pin configurations we can use the same file for both.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <arm/at91/at91board.h>
#include <arm/at91/at91reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_sam9g20.h>
//#include <arm/at91/at91_led.h>
long
board_init(void)
{
/* PIOB's A periph: Turn USART 0's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1);
/* PIOB's A periph: Turn USART 0's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0);
/* PIOB's A periph: Turn USART 1's TX/RX pins */
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0);
/* TWI Two-wire Serial Data */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1);
#if 1
/*
* Turn off Clock to DataFlash, conflicts with MCI clock.
*/
at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2);
at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2);
/* Turn off chip select to DataFlash */
at91_pio_gpio_output(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11, 0);
at91_pio_gpio_set(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11);
at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11);
/* Multimedia Card */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA0_MCDB0, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA1_MCCDB, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA3_MCDB3, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA4_MCDB2, 1);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA5_MCDB1, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK, 1);
at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC9);
#else
/* SPI0 to DataFlash */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA2, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC11,0);
at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8);
at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8);
#endif
/* EMAC */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 , 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC, 0);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA10_ETX2_0, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA11_ETX3_0, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA22_ETXER, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA25_ERX2, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA26_ERX3, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA27_ERXCK, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA28_ECRS, 0);
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA29_ECOL, 0);
return (at91_ramsize());
}

View file

@ -4,14 +4,15 @@ arm/arm/irq_dispatch.S standard
arm/at91/at91_machdep.c standard
arm/at91/at91.c standard
arm/at91/at91_cfata.c optional at91_cfata
arm/at91/at91_st.c standard
arm/at91/at91_mci.c optional at91_mci
arm/at91/at91_nand.c optional nand
arm/at91/at91_pio.c standard
arm/at91/at91_pmc.c standard
arm/at91/at91_rtc.c optional at91_rtc
arm/at91/at91_ssc.c optional at91_ssc
arm/at91/at91_spi.c optional at91_spi \
dependency "spibus_if.h"
arm/at91/at91_ssc.c optional at91_ssc
arm/at91/at91_st.c standard
arm/at91/at91_tc.c optional at91_tc
arm/at91/at91_twi.c optional at91_twi
arm/at91/if_ate.c optional ate
@ -19,6 +20,10 @@ arm/at91/uart_bus_at91usart.c optional uart
arm/at91/uart_cpu_at91rm9200usart.c optional uart
arm/at91/uart_dev_at91usart.c optional uart
#
# All the "systems on a chip" we support
#
arm/at91/at91rm9200.c standard
#
# All the boards we support
#
arm/at91/board_bwct.c optional at91_board_bwct

View file

@ -1,27 +1,36 @@
# $FreeBSD$
arm/arm/cpufunc_asm_arm9.S standard
arm/arm/irq_dispatch.S standard
arm/at91/at91sam9_machdep.c standard
arm/at91/at91sam9.c standard
arm/at91/at91_cfata.c optional at91_cfata
#arm/at91/at91_pit.c standard
arm/at91/at91_machdep.c standard
arm/at91/at91.c standard
arm/at91/at91_mci.c optional at91_mci
arm/at91/at91_nand.c optional nand
arm/at91/at91_pio.c standard
arm/at91/at91_pmc.c standard
arm/at91/at91_pit.c standard
arm/at91/at91_rtc.c optional at91_rtc
arm/at91/at91_ssc.c optional at91_ssc
arm/at91/at91_reset.S standard
arm/at91/at91_rst.c standard
arm/at91/at91_spi.c optional at91_spi \
dependency "spibus_if.h"
arm/at91/at91_ssc.c optional at91_ssc
arm/at91/at91_tc.c optional at91_tc
arm/at91/at91_twi.c optional at91_twi
arm/at91/at91_wdt.c optional at91_wdt
arm/at91/if_ate.c optional ate
arm/at91/if_macb.c optional macb
arm/at91/uart_bus_at91usart.c optional uart
arm/at91/uart_cpu_at91rm9200usart.c optional uart
arm/at91/uart_dev_at91usart.c optional uart
dev/usb/controller/ohci_atmelarm.c optional ohci
#
# All the "systems on a chip" we support
#
arm/at91/at91sam9g20.c optional at91sam9g20
arm/at91/at91sam9260.c optional at91sam9260
#
#
# All the boards we support
#
arm/at91/board_hl201.c optional at91_board_hl201
dev/usb/controller/ohci_atmelarm.c optional ohci
arm/at91/board_sam9g20ek.c optional at91_board_sam9g20ek
arm/at91/board_qila9g20.c optional at91_board_qila9g20

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,8 @@
#ifndef ARM_AT91_IF_ATEREG_H
#define ARM_AT91_IF_ATEREG_H
/* deines begining ETHB_ are EMACB (newer SAM9 hardware) versions only */
#define ETH_CTL 0x00 /* EMAC Control Register */
#define ETH_CFG 0x04 /* EMAC Configuration Register */
#define ETH_SR 0x08 /* EMAC STatus Register */
@ -35,7 +37,7 @@
#define ETH_TCR 0x10 /* EMAC Transmit Control Register */
#define ETH_TSR 0x14 /* EMAC Transmit Status Register */
#define ETH_RBQP 0x18 /* EMAC Receive Buffer Queue Pointer */
/* 0x1c reserved */
#define ETHB_TBQP 0x1c /* reserved */
#define ETH_RSR 0x20 /* EMAC Receive Status Register */
#define ETH_ISR 0x24 /* EMAC Interrupt Status Register */
#define ETH_IER 0x28 /* EMAC Interrupt Enable Register */
@ -74,6 +76,8 @@
#define ETH_SA3H 0xac /* EMAC Specific Address 3 High */
#define ETH_SA4L 0xb0 /* EMAC Specific Address 4 Low */
#define ETH_SA4H 0xb4 /* EMAC Specific Address 4 High */
#define ETHB_TID 0xb8 /* EMAC Type ID Checking */
#define ETHB_UIO 0xC0 /* EMAC User I/O Reg */
/* ETH_CTL */
@ -87,6 +91,9 @@
#define ETH_CTL_WES (1U << 7) /* WES: Write Enable Statistics regs */
#define ETH_CTL_BP (1U << 8) /* BP: Back Pressure */
#define ETHB_CTL_TGO (1U << 9) /* TGO: Transmitter Start */
#define ETHB_CTL_TSTP (1U << 10) /* TSTP: Transmitter Stop */
/* ETH_CFG */
#define ETH_CFG_SPD (1U << 0) /* SPD: Speed 1 == 100: 0 == 10 */
#define ETH_CFG_FD (1U << 1) /* FD: Full duplex */
@ -105,6 +112,17 @@
#define ETH_CFG_RTY (1U << 12) /* RTY: Retry Test*/
#define ETH_CFG_RMII (1U << 13) /* RMII: Reduce MII */
#define ETHB_CFG_JBO (1U << 3) /* JBO: Jumbo Frames */
#define ETHB_CFG_PAE (1U << 13) /* PAE: Pause Enable */
#define ETHB_CFG_RBOF_0 (0U << 14) /* RBOF: Rx Buffer Offset */
#define ETHB_CFG_RBOF_1 (1U << 14) /* RBOF: Rx Buffer Offset */
#define ETHB_CFG_RBOF_2 (3U << 14) /* RBOF: Rx Buffer Offset */
#define ETHB_CFG_RBOF_3 (3U << 14) /* RBOF: Rx Buffer Offset */
#define ETHB_CFG_RCLE (1U << 16) /* RCLE: Rx Length Check Enable */
#define ETHB_CFG_DRFC (1U << 17) /* DRFC: Discard Rx FCS */
#define ETHB_CFG_RHD (1U << 18) /* RHD: RX TX'ed frame in half-duplex */
#define ETHB_CFG_IFCS (1U << 19) /* IFCS: Ignore bad RX FCS */
/* ETH_SR */
#define ETH_SR_LINK (1U << 0) /* Reserved! */
#define ETH_SR_MDIO (1U << 1) /* MDIO pin status */
@ -142,6 +160,10 @@
#define ETH_ISR_ROVR (1U << 10) /* ROVR: RX Overrun */
#define ETH_ISR_ABT (1U << 11) /* ABT: Abort */
/* ETHB_UIO */
#define ETHB_UIO_RMII (1U << 0) /* RMII: Reduce MII */
#define ETHB_UIO_CLKE (1U << 1) /* CLKE: Clock Enable */
/* ETH_MAN */
#define ETH_MAN_BITS 0x40020000 /* HIGH and CODE bits */
#define ETH_MAN_READ (2U << 28)
@ -160,8 +182,11 @@ typedef struct {
uint32_t addr;
#define ETH_CPU_OWNER (1U << 0)
#define ETH_WRAP_BIT (1U << 1)
#define ETH_ADR_MASK ~(EHT_CPU_OWNER | ETH_WRAP_BIT)
uint32_t status;
#define ETH_LEN_MASK 0x7ff
#define ETH_BUF_FIRST (1U << 14) /* Packet matched addr 4 */
#define ETH_BUF_LAST (1U << 15) /* Packet matched addr 4 */
#define ETH_MAC_LOCAL_4 (1U << 23) /* Packet matched addr 4 */
#define ETH_MAC_LOCAL_3 (1U << 24) /* Packet matched addr 3 */
#define ETH_MAC_LOCAL_2 (1U << 25) /* Packet matched addr 2 */
@ -173,4 +198,17 @@ typedef struct {
#define ETH_MAC_ONES (1U << 31) /* Global all ones bcast addr */
} eth_rx_desc_t;
typedef struct {
uint32_t addr;
uint32_t status;
#define ETHB_TX_LEN_MASK 0x7ff
#define ETHB_TX_BUF_LAST (1U << 15) /* Last buffer in packet */
#define ETHB_TX_NOCRC (1U << 16) /* Don't xmit CRC*/
#define ETHB_TX_BUFE (1U << 27) /* Buffers exhausted mid frame */
#define ETHB_TX_TUND (1U << 28) /* Transmit Underrun */
#define ETHB_TX_RTRYE (1U << 29) /* Re-try limit exceeded */
#define ETHB_TX_WRAP (1U << 30) /* Last descritor in list */
#define ETHB_TX_USED (1U << 31) /* Packet Transmitted */
} eth_tx_desc_t;
#endif /* ARM_AT91_IF_ATEREG_H */

View file

@ -67,7 +67,6 @@ __FBSDID("$FreeBSD$");
#include <arm/at91/if_macbvar.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_sam9.h>
#include <arm/at91/at91sam9g20reg.h>
#include <machine/bus.h>
@ -1336,34 +1335,8 @@ macb_attach(device_t dev)
goto out;
}
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, 1<<7, 0);
at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE, 1<<7);
at91_pio_gpio_set_deglitch(AT91SAM9G20_PIOA_BASE, 1<<7, 1);
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA19, 0); /* ETXCK_EREFCK */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA17, 0); /* ERXDV */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA14, 0); /* ERX0 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA15, 0); /* ERX1 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA18, 0); /* ERXER */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA16, 0); /* ETXEN */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA12, 0); /* ETX0 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA13, 0); /* ETX1 */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA21, 0); /* EMDIO */
at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA20, 0); /* EMDC */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA28, 0); /* ECRS */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA29, 0); /* ECOL */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA25, 0); /* ERX2 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA26, 0); /* ERX3 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA27, 0); /* ERXCK */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA23, 0); /* ETX2 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA24, 0); /* ETX3 */
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA22, 0); /* ETXER */
/*setup clock*/
sc->clk = at91_pmc_clock_ref("macb_clk");
sc->clk = at91_pmc_clock_ref(device_get_nameunit(sc->dev));
at91_pmc_clock_enable(sc->clk);
macb_reset(sc);
@ -1391,9 +1364,10 @@ macb_attach(device_t dev)
write_4(sc, EMAC_NCR, MPE_ENABLE); //enable MPE
sc->ifp = ifp = if_alloc(IFT_ETHER);
if (mii_phy_probe(dev, &sc->miibus, macb_ifmedia_upd, macb_ifmedia_sts)) {
device_printf(dev, "Cannot find my PHY.\n");
err = ENXIO;
err = mii_attach(dev, &sc->miibus, ifp, macb_ifmedia_upd,
macb_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0);
if (err != 0) {
device_printf(dev, "attaching PHYs failed\n");
goto out;
}

View file

@ -2,5 +2,8 @@
files "../at91/files.at91sam9"
cpu CPU_ARM9
makeoptions CONF_CFLAGS="-mcpu=arm9 -DAT91SAM9G20"
makeoptions CONF_CFLAGS="-mcpu=arm9"
options PHYSADDR=0x20000000
device at91sam9g20
device at91sam9260

View file

@ -6,5 +6,6 @@ makeoptions KERNPHYSADDR=0x20000000
options KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNVIRTADDR=0xc0000000
options AT91C_MASTER_CLOCK=60000000
device at91_board_kb920x

11
sys/arm/at91/std.qila9g20 Normal file
View file

@ -0,0 +1,11 @@
#$FreeBSD$
include "../at91/std.at91sam9"
options STARTUP_PAGETABLE_ADDR=0x20800000
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNPHYSADDR=0x20000000
options KERNVIRTADDR=0xc0000000
options AT91C_MASTER_CLOCK=((12000000*133)/12)
device at91_board_qila9g20

View file

@ -0,0 +1,15 @@
#$FreeBSD$
include "../at91/std.at91sam9"
options STARTUP_PAGETABLE_ADDR=0x20800000
makeoptions KERNPHYSADDR=0x20000000
makeoptions KERNVIRTADDR=0xc0000000
options KERNPHYSADDR=0x20000000
options KERNVIRTADDR=0xc0000000
#SAM9G20 w/ 18.432 Mhz Clock
#options AT91C_MASTER_CLOCK=((18432000*43)/6)
#SAM9260 w/ 18.432 Mhz Clock
#options AT91C_MASTER_CLOCK=((18432000*97)/18)
device at91_board_sam9g20ek

View file

@ -64,7 +64,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
struct uart_class *class;
class = &at91_usart_class;
if (class->uc_rclk == 0)
if (class->uc_rclk == 0 && at91_master_clock != 0)
class->uc_rclk = at91_master_clock;
di->ops = uart_getops(class);
di->bas.chan = 0;
@ -77,7 +77,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
di->bas.bsh = AT91RM92_BASE + AT91RM92_USART0_BASE;
di->baudrate = 38400;
#else
di->bas.bsh = AT91RM92_BASE + AT91RM92_SYS_BASE + DBGU;
di->bas.bsh = AT91RM92_BASE + AT91RM92_DBGU_BASE;
di->baudrate = 115200;
#endif
di->bas.regshft = 0;

View file

@ -190,9 +190,10 @@ at91_usart_param(struct uart_bas *bas, int baudrate, int databits,
WR4(bas, USART_MR, mr);
/*
* Set the baud rate
* Set the baud rate (only if we know our master clock rate)
*/
WR4(bas, USART_BRGR, BAUD2DIVISOR(baudrate));
if (DEFAULT_RCLK != 0)
WR4(bas, USART_BRGR, BAUD2DIVISOR(baudrate));
/* XXX Need to take possible synchronous mode into account */
return (0);
@ -674,7 +675,10 @@ at91_usart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
case UART_IOCTL_OFLOW:
break;
case UART_IOCTL_BAUD:
WR4(&sc->sc_bas, USART_BRGR, BAUD2DIVISOR(*(int *)data));
/* only if we know our master clock rate */
if (DEFAULT_RCLK != 0)
WR4(&sc->sc_bas, USART_BRGR,
BAUD2DIVISOR(*(int *)data));
return (0);
}
return (EINVAL);

76
sys/arm/conf/DOCKSTAR Normal file
View file

@ -0,0 +1,76 @@
#
# Custom kernel for Seagate DockStar (Marvell SheevaPlug based) devices.
#
# $FreeBSD$
#
ident DOCKSTAR
include "../mv/kirkwood/std.sheevaplug"
options SOC_MV_KIRKWOOD
makeoptions MODULES_OVERRIDE=""
#makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
makeoptions WERROR="-Werror"
options SCHED_4BSD #4BSD scheduler
options INET #InterNETworking
options INET6 #IPv6 communications protocols
options FFS #Berkeley Fast Filesystem
options NFSCLIENT #Network Filesystem Client
options NFSLOCKD #Network Lock Manager
options NFS_ROOT #NFS usable as /, requires NFSCLIENT
options BOOTP
options BOOTP_NFSROOT
options BOOTP_NFSV3
options BOOTP_COMPAT
options BOOTP_WIRED_TO=mge0
# Root fs on USB device
#options ROOTDEVNAME=\"ufs:/dev/da0a\"
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 MUTEX_NOINLINE
options RWLOCK_NOINLINE
options NO_FFS_SNAPSHOT
options NO_SWAPPING
# Debugging
options ALT_BREAK_TO_DEBUGGER
options DDB
options KDB
# Pseudo devices
device md
device random
device pty
device loop
# Serial ports
device uart
# Networking
device ether
device mge # Marvell Gigabit Ethernet controller
device mii
device bpf
options HZ=1000
options DEVICE_POLLING
device vlan
# USB
options USB_DEBUG # enable debug msgs
device usb
device ehci
device umass
device scbus
device pass
device da
# Flattened Device Tree
options FDT
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=dockstar.dts

153
sys/arm/conf/QILA9G20 Normal file
View file

@ -0,0 +1,153 @@
# Kernel configuration for Calao Syatems QIL-A9G20 development card
# http://www.calao-systems.com
#
# 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$
ident QILA9G20
include "../at91/std.qila9g20"
#To statically compile in device wiring instead of /boot/device.hints
hints "QILA9G20.hints"
makeoptions MODULES_OVERRIDE=""
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
options DDB
options KDB
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 MD_ROOT_SIZE=4096 # 3MB ram disk
options NFSCLIENT #Network Filesystem Client
#options NFSSERVER #Network Filesystem Server
#options NFSLOCKD #Network Lock Manager
#options NFS_ROOT #NFS usable as /, requires NFSCLIENT
#options BOOTP_NFSROOT
#options BOOTP
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=ate0
#options BOOTP_COMPAT
options ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
options ALT_BREAK_TO_DEBUGGER
#options MSDOSFS #MSDOS Filesystem
#options CD9660 #ISO 9660 Filesystem
#options PROCFS #Process filesystem (requires PSEUDOFS)
#options PSEUDOFS #Pseudo-filesystem framework
#options SCSI_DELAY=5000 #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 SYSCTL_OMIT_DESCR
options MUTEX_NOINLINE
options RWLOCK_NOINLINE
options NO_FFS_SNAPSHOT
options NO_SWAPPING
# Debugging for use in -current
#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
#options DIAGNOSTIC
device random
device pty
device loop
device bpf
device ether
device md
device uart # Serial Ports
# Ethernet
device ate # Ethernet Driver
#device macb # Alternate Ethernet driver
device mii
option AT91_ATE_USE_RMII
device at91_twi # TWI: Two Wire Interface (EEPROM)
device at91_wdt # WDT: Watchdog timer
# NOTE: SPI DataFlash and mci/mmc/mmcsd have hardware
# confilict on this card. Use one or the other.
# see board_sam9g20ek.c
# SPI: Data Flash
#device at91_spi # SPI:
#device spibus
#device at45d # at45db642 and maybe others
# MMC/SD
device at91_mci
device mmc
device mmcsd
option AT91_MCI_HAS_4WIRE
# iic
device iic
device iicbus
device icee
# SCSI peripherals
device scbus # SCSI bus (required for SCSI)
device da # Direct Access (disks)
device cd # CD
device pass # Passthrough device (direct SCSI access)
# USB support
device ohci # OHCI localbus->USB interface
device usb # USB Bus (required)
device umass # Disks/Mass storage - Requires scbus and da
device uhid # "Human Interface Devices"
#device ulpt # Printer
#device udbp # USB Double Bulk Pipe devices
# USB Ethernet, requires miibus
device miibus
#device aue # ADMtek USB Ethernet
#device axe # ASIX Electronics USB Ethernet
#device cdce # Generic USB over Ethernet
#device cue # CATC USB Ethernet
#device kue # Kawasaki LSI USB Ethernet
#device rue # RealTek RTL8150 USB Ethernet
device udav # Davicom DM9601E USB
# USB Wireless
#device rum # Ralink Technology RT2501USB wireless NICs
#device uath # Atheros AR5523 wireless NICs
#device ural # Ralink Technology RT2500USB wireless NICs
#device zyd # ZyDAS zb1211/zb1211b wireless NICs
# Wireless NIC cards
#device wlan # 802.11 support
#device wlan_wep # 802.11 WEP support
#device wlan_ccmp # 802.11 CCMP support
#device wlan_tkip # 802.11 TKIP support
#device wlan_amrr # AMRR transmit rate control algorithm

View file

@ -0,0 +1,9 @@
# $FreeBSD$
# Kernel configuration hits for Calao Syatems QIL-A9G20 development card
# http://www.calao-systems.com
# STMicroelctrtronics M41T94 Real-Time Clock
# on SPI0 NPCS0
# STMicroelctrtronics M95640 8k x 8 EEPROM
# on SPI0 NPCS1

153
sys/arm/conf/SAM9G20EK Normal file
View file

@ -0,0 +1,153 @@
# Kernel configuration for Atmel AT91SAM9G20EK Rev B. development card
#
# 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$
ident SAM9G20EK
include "../at91/std.sam9g20ek"
#To statically compile in device wiring instead of /boot/device.hints
hints "SAM9G20EK.hints"
makeoptions MODULES_OVERRIDE=""
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
options DDB
options KDB
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 MD_ROOT_SIZE=4096 # 3MB ram disk
options NFSCLIENT #Network Filesystem Client
#options NFSSERVER #Network Filesystem Server
#options NFSLOCKD #Network Lock Manager
#options NFS_ROOT #NFS usable as /, requires NFSCLIENT
#options BOOTP_NFSROOT
#options BOOTP
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=ate0
#options BOOTP_COMPAT
options ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
options ALT_BREAK_TO_DEBUGGER
#options MSDOSFS #MSDOS Filesystem
#options CD9660 #ISO 9660 Filesystem
#options PROCFS #Process filesystem (requires PSEUDOFS)
#options PSEUDOFS #Pseudo-filesystem framework
#options SCSI_DELAY=5000 #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 SYSCTL_OMIT_DESCR
options MUTEX_NOINLINE
options RWLOCK_NOINLINE
options NO_FFS_SNAPSHOT
options NO_SWAPPING
# Debugging for use in -current
#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
#options DIAGNOSTIC
device random
device pty
device loop
device bpf
device ether
device md
device uart # Serial Ports
# Ethernet
device ate # Ethernet Driver
#device macb # Alternate Ethernet driver
device mii
option AT91_ATE_USE_RMII
device at91_twi # TWI: Two Wire Interface (EEPROM)
device at91_wdt # WDT: Watchdog timer
# NOTE: SPI DataFlash and mci/mmc/mmcsd have hardware
# confilict on this card. Use one or the other.
# see board_sam9g20ek.c
# SPI: Data Flash
#device at91_spi # SPI:
#device spibus
#device at45d # at45db642 and maybe others
# MMC/SD
device at91_mci
device mmc
device mmcsd
option AT91_MCI_SLOT_B
option AT91_MCI_HAS_4WIRE
# iic
device iic
device iicbus
device icee
# SCSI peripherals
device scbus # SCSI bus (required for SCSI)
device da # Direct Access (disks)
device cd # CD
device pass # Passthrough device (direct SCSI access)
# USB support
device ohci # OHCI localbus->USB interface
device usb # USB Bus (required)
device umass # Disks/Mass storage - Requires scbus and da
device uhid # "Human Interface Devices"
#device ulpt # Printer
#device udbp # USB Double Bulk Pipe devices
# USB Ethernet, requires miibus
device miibus
#device aue # ADMtek USB Ethernet
#device axe # ASIX Electronics USB Ethernet
#device cdce # Generic USB over Ethernet
#device cue # CATC USB Ethernet
#device kue # Kawasaki LSI USB Ethernet
#device rue # RealTek RTL8150 USB Ethernet
device udav # Davicom DM9601E USB
# USB Wireless
#device rum # Ralink Technology RT2501USB wireless NICs
#device uath # Atheros AR5523 wireless NICs
#device ural # Ralink Technology RT2500USB wireless NICs
#device zyd # ZyDAS zb1211/zb1211b wireless NICs
# Wireless NIC cards
#device wlan # 802.11 support
#device wlan_wep # 802.11 WEP support
#device wlan_ccmp # 802.11 CCMP support
#device wlan_tkip # 802.11 TKIP support
#device wlan_amrr # AMRR transmit rate control algorithm

View file

@ -0,0 +1,10 @@
# $FreeBSD$
#
# EEPROM
hint.icee.0.at="iicbus0"
hint.icee.0.addr=0xa0
hint.icee.0.type=16
hint.icee.0.size=65536
hint.icee.0.rd_sz=256
hint.icee.0.wr_sz=256

View file

@ -353,10 +353,11 @@ ece_attach(device_t dev)
}
ece_set_mac(sc, eaddr);
sc->ifp = ifp = if_alloc(IFT_ETHER);
if (mii_phy_probe(dev, &sc->miibus, ece_ifmedia_upd,
ece_ifmedia_sts)) {
device_printf(dev, "Cannot find my PHY.\n");
err = ENXIO;
/* Only one PHY at address 0 in this device. */
err = mii_attach(dev, &sc->miibus, ifp, ece_ifmedia_upd,
ece_ifmedia_sts, BMSR_DEFCAPMASK, 0, MII_OFFSET_ANY, 0);
if (err != 0) {
device_printf(dev, "attaching PHYs failed\n");
goto out;
}
ifp->if_softc = sc;
@ -1904,9 +1905,6 @@ static int
ece_miibus_readreg(device_t dev, int phy, int reg)
{
struct ece_softc *sc;
/* Only one phy in this device. */
if (phy>0)
return (0);
sc = device_get_softc(dev);
return (phy_read(sc, phy, reg));
}

View file

@ -400,6 +400,7 @@ extern unsigned arm10_dcache_index_max;
extern unsigned arm10_dcache_index_inc;
u_int sheeva_control_ext (u_int, u_int);
void sheeva_cpu_sleep (int);
void sheeva_setttb (u_int);
void sheeva_dcache_wbinv_range (vm_offset_t, vm_size_t);
void sheeva_dcache_inv_range (vm_offset_t, vm_size_t);

View file

@ -76,8 +76,14 @@ __ElfType(Auxinfo);
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_EXECPATH 15 /* Path to the executable. */
#define AT_CANARY 16 /* Canary for SSP */
#define AT_CANARYLEN 17 /* Length of the canary. */
#define AT_OSRELDATE 18 /* OSRELDATE. */
#define AT_NCPUS 19 /* Number of CPUs. */
#define AT_PAGESIZES 20 /* Pagesizes. */
#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
#define AT_COUNT 16 /* Count of defined aux entry types. */
#define AT_COUNT 22 /* Count of defined aux entry types. */
#define R_ARM_COUNT 33 /* Count of defined relocation types. */

View file

@ -710,7 +710,7 @@ sata_channel_status(device_t dev)
if ((icr & SATA_ICR_DEV(ch->unit)) || iecr) {
/* Disable EDMA before accessing SATA registers */
sata_edma_ctrl(dev, 0);
ata_sata_phy_check_events(dev);
ata_sata_phy_check_events(dev, -1);
/* Ack device and error interrupt */
SATA_OUTL(sc, SATA_ICR, ~SATA_ICR_DEV(ch->unit));

View file

@ -178,14 +178,14 @@ mv_hardclock(void *arg)
struct mv_timer_softc *sc;
uint32_t irq_cause;
sc = (struct mv_timer_softc *)arg;
if (sc->et.et_active)
sc->et.et_event_cb(&sc->et, sc->et.et_arg);
irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
irq_cause &= ~(IRQ_TIMER0);
write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
sc = (struct mv_timer_softc *)arg;
if (sc->et.et_active)
sc->et.et_event_cb(&sc->et, sc->et.et_arg);
return (FILTER_HANDLED);
}
@ -394,6 +394,8 @@ mv_timer_start(struct eventtimer *et,
val |= CPU_TIMER0_EN;
if (period != NULL)
val |= CPU_TIMER0_AUTO;
else
val &= ~CPU_TIMER0_AUTO;
mv_set_timer_control(val);
return (0);
}

View file

@ -137,7 +137,6 @@ struct npe_softc {
int rx_freeqid; /* rx free buffers qid */
int tx_qid; /* tx qid */
int tx_doneqid; /* tx completed qid */
int sc_phy; /* PHY id */
struct ifmib_iso_8802_3 mibdata;
bus_dma_tag_t sc_stats_tag; /* bus dma tag for stats block */
struct npestats *sc_stats;
@ -668,7 +667,7 @@ static int
npe_activate(device_t dev)
{
struct npe_softc *sc = device_get_softc(dev);
int error, i, macbase, miibase;
int error, i, macbase, miibase, phy;
/*
* Setup NEP ID, MAC, and MII bindings. We allow override
@ -693,8 +692,8 @@ npe_activate(device_t dev)
}
/* PHY */
if (!override_unit(dev, "phy", &sc->sc_phy, 0, MII_NPHY-1))
sc->sc_phy = npeconfig[sc->sc_npeid].phy;
if (!override_unit(dev, "phy", &phy, 0, MII_NPHY - 1))
phy = npeconfig[sc->sc_npeid].phy;
if (!override_addr(dev, "mii", &miibase))
miibase = npeconfig[sc->sc_npeid].miibase;
device_printf(sc->sc_dev, "MII at 0x%x\n", miibase);
@ -721,10 +720,12 @@ npe_activate(device_t dev)
return error;
}
/* probe for PHY */
if (mii_phy_probe(dev, &sc->sc_mii, npe_ifmedia_update, npe_ifmedia_status)) {
device_printf(dev, "cannot find PHY %d.\n", sc->sc_phy);
return ENXIO;
/* attach PHY */
error = mii_attach(dev, &sc->sc_mii, sc->sc_ifp, npe_ifmedia_update,
npe_ifmedia_status, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0);
if (error != 0) {
device_printf(dev, "attaching PHYs failed\n");
return error;
}
error = npe_dma_setup(sc, &sc->txdma, "tx", npe_txbuf, NPE_MAXSEG);
@ -1700,8 +1701,6 @@ npe_miibus_readreg(device_t dev, int phy, int reg)
struct npe_softc *sc = device_get_softc(dev);
uint32_t v;
if (phy != sc->sc_phy) /* XXX no auto-detect */
return 0xffff;
v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL) | NPE_MII_GO;
npe_mii_mdio_write(sc, NPE_MAC_MDIO_CMD, v);
if (npe_mii_mdio_wait(sc))
@ -1717,8 +1716,6 @@ npe_miibus_writereg(device_t dev, int phy, int reg, int data)
struct npe_softc *sc = device_get_softc(dev);
uint32_t v;
if (phy != sc->sc_phy) /* XXX */
return (0);
v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL)
| data | NPE_MII_WRITE
| NPE_MII_GO;

View file

@ -369,7 +369,7 @@ ixp425_hinted_child(device_t bus, const char *dname, int dunit)
}
static device_t
ixp425_add_child(device_t dev, int order, const char *name, int unit)
ixp425_add_child(device_t dev, u_int order, const char *name, int unit)
{
device_t child;
struct ixp425_ivar *ivar;

View file

@ -1,31 +1,13 @@
# $FreeBSD$
.include <bsd.own.mk>
.include <bsd.arch.inc.mk>
.if ${MK_FORTH} != "no"
# Build the add-in FORTH interpreter.
SUBDIR+= ficl
.endif
# Build EFI library.
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE} == "i386" || ${MACHINE_ARCH} == "ia64"
SUBDIR+= efi
.endif
# Build Open Firmware library.
.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64" || ${MACHINE_ARCH} == "sparc64"
SUBDIR+= ofw
.endif
# Build U-Boot library.
.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64" || ${MACHINE_ARCH} == "arm"
SUBDIR+= uboot
.endif
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE} == "i386"
SUBDIR+= zfs
.endif
.if ${MK_FDT} != "no"
SUBDIR+= fdt
.endif

4
sys/boot/Makefile.amd64 Normal file
View file

@ -0,0 +1,4 @@
# $FreeBSD$
SUBDIR+= efi
SUBDIR+= zfs

3
sys/boot/Makefile.arm Normal file
View file

@ -0,0 +1,3 @@
# $FreeBSD$
SUBDIR+= uboot

4
sys/boot/Makefile.i386 Normal file
View file

@ -0,0 +1,4 @@
# $FreeBSD$
SUBDIR+= efi
SUBDIR+= zfs

3
sys/boot/Makefile.ia64 Normal file
View file

@ -0,0 +1,3 @@
# $FreeBSD$
SUBDIR+= efi

4
sys/boot/Makefile.pc98 Normal file
View file

@ -0,0 +1,4 @@
# $FreeBSD$
# Blank, to override Makefile.i386 since Makefile.$MACHINE is included before
# Makefile.$MACHINE_ARCH

View file

@ -0,0 +1,4 @@
# $FreeBSD$
SUBDIR+= ofw
SUBDIR+= uboot

View file

@ -0,0 +1,3 @@
# $FreeBSD$
SUBDIR+= ofw

View file

@ -20,7 +20,7 @@ NO_MAN=
KERNPHYSADDR=0x180000
KERNVIRTADDR=${KERNPHYSADDR}
BOOT_STACK=0x200000-4
M=${MACHINE_ARCH}
M=${MACHINE}
LDFLAGS=-e ${KERNPHYSADDR} -EB -T ldscript.${M}
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
S=${.CURDIR}/../../../..

View file

@ -77,7 +77,7 @@ CLEANFILES+= vers.c loader.help
CFLAGS+= -ffreestanding
LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.arm
LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH}
# Pull in common loader code
.PATH: ${.CURDIR}/../../uboot/common

View file

@ -4,19 +4,19 @@ SRCS+= boot.c commands.c console.c devopen.c interp.c
SRCS+= interp_backslash.c interp_parse.c ls.c misc.c
SRCS+= module.c panic.c
.if ${MACHINE} == "i386" || ${MACHINE_ARCH} == "amd64"
.if ${MACHINE} == "i386" || ${MACHINE_CPUARCH} == "amd64"
SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c
SRCS+= load_elf64.c load_elf64_obj.c reloc_elf64.c
.elif ${MACHINE} == "ia64"
.elif ${MACHINE_CPUARCH} == "ia64"
SRCS+= load_elf64.c load_elf64_obj.c reloc_elf64.c
.elif ${MACHINE} == "pc98"
SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c
.elif ${MACHINE_ARCH} == "arm"
.elif ${MACHINE_CPUARCH} == "arm"
SRCS+= load_elf32.c reloc_elf32.c
.elif ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64"
.elif ${MACHINE_CPUARCH} == "powerpc"
SRCS+= load_elf32.c reloc_elf32.c
SRCS+= load_elf64.c reloc_elf64.c
.elif ${MACHINE_ARCH} == "sparc64"
.elif ${MACHINE_CPUARCH} == "sparc64"
SRCS+= load_elf64.c reloc_elf64.c
.endif

108
sys/boot/common/crc32.c Normal file
View file

@ -0,0 +1,108 @@
/*-
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*/
/*
* First, the polynomial itself and its table of feedback terms. The
* polynomial is
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
*
* Note that we take it "backwards" and put the highest-order term in
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
* the MSB being 1
*
* Note that the usual hardware shift register implementation, which
* is what we're using (we're merely optimizing it by doing eight-bit
* chunks at a time) shifts bits into the lowest-order term. In our
* implementation, that means shifting towards the right. Why do we
* do it this way? Because the calculated CRC must be transmitted in
* order from highest-order term to lowest-order term. UARTs transmit
* characters in order from LSB to MSB. By storing the CRC this way
* we hand it to the UART in the order low-byte to high-byte; the UART
* sends each low-bit to hight-bit; and the result is transmission bit
* by bit from highest- to lowest-order term without requiring any bit
* shuffling on our part. Reception works similarly
*
* The feedback terms table consists of 256, 32-bit entries. Notes
*
* The table can be generated at runtime if desired; code to do so
* is shown later. It might not be obvious, but the feedback
* terms simply represent the results of eight shift/xor opera
* tions for all combinations of data and CRC register values
*
* The values must be right-shifted by eight bits by the "updcrc
* logic; the shift must be unsigned (bring in zeroes). On some
* hardware you could probably optimize the shift in assembler by
* using byte-swap instructions
* polynomial $edb88320
*
*
* CRC32 code derived from work by Gary S. Brown.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include "crc32.h"
static uint32_t crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
uint32_t
crc32(const void *buf, size_t size)
{
const uint8_t *p = buf;
uint32_t crc;
crc = ~0U;
while (size--)
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return (crc ^ ~0U);
}

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