From 90556fb8d47e7b68fd301dde9dbb3ae7495cf323 Mon Sep 17 00:00:00 2001 From: Apple Date: Wed, 13 Aug 2003 02:29:46 +0000 Subject: [PATCH] xnu-344.26.tar.gz --- bsd/conf/version.minor | 2 +- bsd/hfs/hfs_vnops.c | 90 +++++++++-- bsd/kern/kern_sysctl.c | 2 + bsd/net/ether_if_module.c | 18 +++ bsd/netinet/if_ether.c | 22 +++ bsd/netinet/in_var.h | 8 + bsd/nfs/krpc_subr.c | 33 +++- bsd/nfs/nfs_boot.c | 143 ++++++++++++------ bsd/nfs/nfs_vfsops.c | 67 ++++---- bsd/nfs/nfsdiskless.h | 5 +- bsd/nfs/rpcv2.h | 1 + bsd/sys/sysctl.h | 6 +- config/System.kext/Contents/Info.plist | 8 +- .../PlugIns/AppleNMI.kext/Contents/Info.plist | 6 +- .../Contents/Info.plist | 6 +- .../BSDKernel.kext/Contents/Info.plist | 6 +- .../IOADBFamily.kext/Contents/Info.plist | 6 +- .../PlugIns/IOKit.kext/Contents/Info.plist | 6 +- .../IONVRAMFamily.kext/Contents/Info.plist | 6 +- .../Contents/Info.plist | 6 +- .../PlugIns/Libkern.kext/Contents/Info.plist | 6 +- .../PlugIns/Mach.kext/Contents/Info.plist | 6 +- iokit/IOKit/IOService.h | 1 + iokit/Kernel/IOCPU.cpp | 8 +- iokit/Kernel/IOMemoryDescriptor.cpp | 2 +- iokit/Kernel/IOServicePM.cpp | 84 +++++++--- iokit/KernelConfigTables.cpp | 20 +-- iokit/conf/version.minor | 2 +- libkern/conf/version.minor | 2 +- libsa/conf/version.minor | 2 +- osfmk/conf/kernelversion.minor | 2 +- osfmk/conf/version.minor | 2 +- osfmk/kern/task.c | 10 +- osfmk/mach/vm_param.h | 115 ++++++++++++-- osfmk/ppc/FirmwareC.c | 10 +- osfmk/ppc/cpu.c | 6 +- osfmk/vm/task_working_set.c | 75 +++++++-- osfmk/vm/task_working_set.h | 4 + pexpert/conf/version.minor | 2 +- pexpert/pexpert/pexpert.h | 3 + pexpert/ppc/pe_clock_speed.c | 7 +- pexpert/ppc/pe_identify_machine.c | 10 +- pexpert/ppc/pe_init.c | 4 +- 43 files changed, 622 insertions(+), 208 deletions(-) diff --git a/bsd/conf/version.minor b/bsd/conf/version.minor index 00750edc0..b8626c4cf 100644 --- a/bsd/conf/version.minor +++ b/bsd/conf/version.minor @@ -1 +1 @@ -3 +4 diff --git a/bsd/hfs/hfs_vnops.c b/bsd/hfs/hfs_vnops.c index 7412131ca..129c95530 100644 --- a/bsd/hfs/hfs_vnops.c +++ b/bsd/hfs/hfs_vnops.c @@ -58,6 +58,8 @@ extern uid_t console_user; +extern unsigned long strtoul(const char *, char **, int); + /* Global vfs data structures for hfs */ @@ -1076,6 +1078,23 @@ hfs_exchange(ap) hfs_chashinsert(from_cp); hfs_chashinsert(to_cp); + + /* + * When a file moves out of "Cleanup At Startup" + * we can drop its NODUMP status. + */ + if ((from_cp->c_flags & UF_NODUMP) && + (from_cp->c_parentcnid != to_cp->c_parentcnid)) { + from_cp->c_flags &= ~UF_NODUMP; + from_cp->c_flag |= C_CHANGE; + } + + if ((to_cp->c_flags & UF_NODUMP) && + (to_cp->c_parentcnid != from_cp->c_parentcnid)) { + to_cp->c_flags &= ~UF_NODUMP; + to_cp->c_flag |= C_CHANGE; + } + Err_Exit: if (to_rvp) vrele(to_rvp); @@ -1155,8 +1174,11 @@ hfs_fsync(ap) * When MNT_WAIT is requested and the zero fill timeout * has expired then we must explicitly zero out any areas * that are currently marked invalid (holes). + * + * Files with NODUMP can bypass zero filling here. */ if ((wait || (cp->c_flag & C_ZFWANTSYNC)) && + ((cp->c_flags & UF_NODUMP) == 0) && UBCINFOEXISTS(vp) && (fp = VTOF(vp)) && cp->c_zftimeout != 0) { int devblksize; @@ -1682,15 +1704,8 @@ hfs_remove(ap) cp->c_mode = 0; /* Suppress VOP_UPDATES */ error = VOP_TRUNCATE(rvp, (off_t)0, IO_NDELAY, NOCRED, p); cp->c_mode = mode; - if (error && !dataforkbusy) + if (error) goto out; - else { - /* - * XXX could also force an update on vp - * and fail the remove. - */ - error = 0; - } truncated = 1; } } @@ -1820,10 +1835,11 @@ hfs_remove(ap) } else /* Not busy */ { - if (vp->v_type == VDIR && cp->c_entries > 0) - panic("hfs_remove: attempting to delete a non-empty directory!"); - if (vp->v_type != VDIR && cp->c_blocks > 0) - panic("hfs_remove: attempting to delete a non-empty file!"); + if (cp->c_blocks > 0) { + printf("hfs_remove: attempting to delete a non-empty file!"); + error = EBUSY; + goto out; + } /* Lock catalog b-tree */ error = hfs_metafilelocking(hfsmp, kHFSCatalogFileID, LK_EXCLUSIVE, p); @@ -1832,7 +1848,7 @@ hfs_remove(ap) error = cat_delete(hfsmp, &cp->c_desc, &cp->c_attr); - if (error && error != ENXIO && truncated) { + if (error && error != ENXIO && error != ENOENT && truncated) { if ((cp->c_datafork && cp->c_datafork->ff_data.cf_size != 0) || (cp->c_rsrcfork && cp->c_rsrcfork->ff_data.cf_size != 0)) { panic("hfs: remove: couldn't delete a truncated file! (%d, data sz %lld; rsrc sz %lld)", @@ -2211,6 +2227,21 @@ hfs_rename(ap) fdcp = VTOC(fdvp); fcp = VTOC(fvp); + /* + * When a file moves out of "Cleanup At Startup" + * we can drop its NODUMP status. + */ + if ((fcp->c_flags & UF_NODUMP) && + (fvp->v_type == VREG) && + (fdvp != tdvp) && + (fdcp->c_desc.cd_nameptr != NULL) && + (strcmp(fdcp->c_desc.cd_nameptr, "Cleanup At Startup") == 0)) { + fcp->c_flags &= ~UF_NODUMP; + fcp->c_flag |= C_CHANGE; + tv = time; + (void) VOP_UPDATE(fvp, &tv, &tv, 0); + } + hfs_global_shared_lock_acquire(hfsmp); grabbed_lock = 1; if (hfsmp->jnl) { @@ -3400,7 +3431,38 @@ exit: if ((cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI); - vput(dvp); + + /* + * Check if a file is located in the "Cleanup At Startup" + * directory. If it is then tag it as NODUMP so that we + * can be lazy about zero filling data holes. + */ + if ((error == 0) && (vnodetype == VREG) && + (dcp->c_desc.cd_nameptr != NULL) && + (strcmp(dcp->c_desc.cd_nameptr, "Cleanup At Startup") == 0)) { + struct vnode *ddvp; + cnid_t parid; + + parid = dcp->c_parentcnid; + vput(dvp); + dvp = NULL; + + /* + * The parent of "Cleanup At Startup" should + * have the ASCII name of the userid. + */ + if (VFS_VGET(HFSTOVFS(hfsmp), &parid, &ddvp) == 0) { + if (VTOC(ddvp)->c_desc.cd_nameptr && + (cp->c_uid == strtoul(VTOC(ddvp)->c_desc.cd_nameptr, 0, 0))) { + cp->c_flags |= UF_NODUMP; + cp->c_flag |= C_CHANGE; + } + vput(ddvp); + } + } + + if (dvp) + vput(dvp); // XXXdbg if (started_tr) { diff --git a/bsd/kern/kern_sysctl.c b/bsd/kern/kern_sysctl.c index 6aefc6796..cf5ec167c 100644 --- a/bsd/kern/kern_sysctl.c +++ b/bsd/kern/kern_sysctl.c @@ -517,6 +517,8 @@ hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) return (sysctl_rdint(oldp, oldlenp, newp, gPEClockFrequencyInfo.bus_clock_rate_hz)); case HW_CPU_FREQ: return (sysctl_rdint(oldp, oldlenp, newp, gPEClockFrequencyInfo.cpu_clock_rate_hz)); + case HW_TB_FREQ: + return (sysctl_rdint(oldp, oldlenp, newp, gPEClockFrequencyInfo.timebase_frequency_hz)); #if __ppc__ case HW_VECTORUNIT: return (sysctl_rdint(oldp, oldlenp, newp, cpu_info.vector_unit)); diff --git a/bsd/net/ether_if_module.c b/bsd/net/ether_if_module.c index 27e9dd8b8..027dd404e 100644 --- a/bsd/net/ether_if_module.c +++ b/bsd/net/ether_if_module.c @@ -332,6 +332,24 @@ int ether_demux(ifp, m, frame_header, proto) m->m_flags |= M_BCAST; else m->m_flags |= M_MCAST; + } else { + /* + * When the driver is put into promiscuous mode we may receive unicast + * frames that are not intended for our interfaces. They are filtered + * here to keep them from traveling further up the stack to code that + * is not expecting them or prepared to deal with them. In the near + * future, the filtering done here will be moved even further down the + * stack into the IONetworkingFamily, preventing even interface + * filter NKE's from receiving promiscuous packets. Please use BPF. + */ + #define ETHER_CMP(x, y) ( ((u_int16_t *) x)[0] != ((u_int16_t *) y)[0] || \ + ((u_int16_t *) x)[1] != ((u_int16_t *) y)[1] || \ + ((u_int16_t *) x)[2] != ((u_int16_t *) y)[2] ) + + if (ETHER_CMP(eh->ether_dhost, ((struct arpcom *) ifp)->ac_enaddr)) { + m_freem(m); + return EJUSTRETURN; + } } data = mtod(m, u_int8_t*); diff --git a/bsd/netinet/if_ether.c b/bsd/netinet/if_ether.c index 07e99d6eb..d9b7bbb86 100644 --- a/bsd/netinet/if_ether.c +++ b/bsd/netinet/if_ether.c @@ -642,9 +642,31 @@ in_arpinput(m) return; } if (isaddr.s_addr == myaddr.s_addr) { + struct kev_msg ev_msg; + struct kev_in_collision *in_collision; + u_char storage[sizeof(struct kev_in_collision) + 6]; + in_collision = (struct kev_in_collision*)storage; + log(LOG_ERR, "duplicate IP address %s sent from ethernet address %s\n", inet_ntoa(isaddr), ether_sprintf(buf, ea->arp_sha)); + + /* Send a kernel event so anyone can learn of the conflict */ + in_collision->link_data.if_family = ac->ac_if.if_family; + in_collision->link_data.if_unit = ac->ac_if.if_unit; + strncpy(&in_collision->link_data.if_name[0], ac->ac_if.if_name, IFNAMSIZ); + in_collision->ia_ipaddr = isaddr; + in_collision->hw_len = ETHER_ADDR_LEN; + bcopy((caddr_t)ea->arp_sha, (caddr_t)in_collision->hw_addr, sizeof(ea->arp_sha)); + ev_msg.vendor_code = KEV_VENDOR_APPLE; + ev_msg.kev_class = KEV_NETWORK_CLASS; + ev_msg.kev_subclass = KEV_INET_SUBCLASS; + ev_msg.event_code = KEV_INET_ARPCOLLISION; + ev_msg.dv[0].data_ptr = in_collision; + ev_msg.dv[0].data_length = sizeof(struct kev_in_collision) + 6; + ev_msg.dv[1].data_length = 0; + kev_post_msg(&ev_msg); + itaddr = myaddr; goto reply; } diff --git a/bsd/netinet/in_var.h b/bsd/netinet/in_var.h index 0c9d8c829..c4ac2f13e 100644 --- a/bsd/netinet/in_var.h +++ b/bsd/netinet/in_var.h @@ -115,6 +115,13 @@ struct kev_in_data { struct in_addr ia_dstaddr; }; +struct kev_in_collision { + struct net_event_data link_data; /* link colliding arp was received on */ + struct in_addr ia_ipaddr; /* IP address we and another node are using */ + u_char hw_len; /* length of hardware address */ + u_char hw_addr[0]; /* variable length hardware address */ +}; + /* * Define inet event subclass and specific inet events. @@ -128,6 +135,7 @@ struct kev_in_data { #define KEV_INET_SIFDSTADDR 4 #define KEV_INET_SIFBRDADDR 5 #define KEV_INET_SIFNETMASK 6 +#define KEV_INET_ARPCOLLISION 7 /* use kev_in_collision */ #endif /* __APPLE__ */ /* diff --git a/bsd/nfs/krpc_subr.c b/bsd/nfs/krpc_subr.c index 98a7eee68..f88ecd2f4 100644 --- a/bsd/nfs/krpc_subr.c +++ b/bsd/nfs/krpc_subr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -401,13 +401,40 @@ krpc_call(sa, prog, vers, func, data, from_p) if (reply->rp_astatus != 0) { error = ntohl(reply->rp_u.rpu_errno); printf("rpc denied, error=%d\n", error); - continue; + /* convert rpc error to errno */ + switch (error) { + case RPC_MISMATCH: + error = ERPCMISMATCH; + break; + case RPC_AUTHERR: + error = EAUTH; + break; + } + goto out; } /* Did the call succeed? */ if ((error = ntohl(reply->rp_u.rpu_ok.rp_rstatus)) != 0) { printf("rpc status=%d\n", error); - continue; + /* convert rpc error to errno */ + switch (error) { + case RPC_PROGUNAVAIL: + error = EPROGUNAVAIL; + break; + case RPC_PROGMISMATCH: + error = EPROGMISMATCH; + break; + case RPC_PROCUNAVAIL: + error = EPROCUNAVAIL; + break; + case RPC_GARBAGE: + error = EINVAL; + break; + case RPC_SYSTEM_ERR: + error = EIO; + break; + } + goto out; } goto gotreply; /* break two levels */ diff --git a/bsd/nfs/nfs_boot.c b/bsd/nfs/nfs_boot.c index 0590f4c49..98dbc2367 100644 --- a/bsd/nfs/nfs_boot.c +++ b/bsd/nfs/nfs_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -130,6 +130,14 @@ int nfs_boot_init(nd, procp) panic("nfs_boot_init: no ether"); } +int nfs_boot_getfh(nd, procp, v3) + struct nfs_diskless *nd; + struct proc *procp; + int v3; +{ + panic("nfs_boot_getfh: no ether"); +} + #else /* NETHER */ /* @@ -159,11 +167,11 @@ static int bp_getfile __P((struct sockaddr_in *bpsin, char *key, struct sockaddr_in *mdsin, char *servname, char *path)); /* mountd RPC */ -static int md_mount __P((struct sockaddr_in *mdsin, char *path, - u_char *fh)); +static int md_mount __P((struct sockaddr_in *mdsin, char *path, int v3, + u_char *fhp, u_long *fhlenp)); /* other helpers */ -static int get_file_handle __P((char *pathname, struct nfs_dlmount *ndmntp)); +static int get_file_handle __P((struct nfs_dlmount *ndmntp)); #define IP_FORMAT "%d.%d.%d.%d" @@ -191,7 +199,6 @@ nfs_boot_init(nd, procp) boolean_t do_bpgetfile = TRUE; int error = 0; struct in_addr my_ip; - char * root_path = NULL; struct sockaddr_in * sin_p; /* by this point, networking must already have been configured */ @@ -202,14 +209,14 @@ nfs_boot_init(nd, procp) } /* get the root path information */ - MALLOC(root_path, char *, MAXPATHLEN, M_TEMP, M_WAITOK); + MALLOC_ZONE(nd->nd_root.ndm_path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK); sin_p = &nd->nd_root.ndm_saddr; bzero((caddr_t)sin_p, sizeof(*sin_p)); sin_p->sin_len = sizeof(*sin_p); sin_p->sin_family = AF_INET; if (netboot_rootpath(&sin_p->sin_addr, nd->nd_root.ndm_host, sizeof(nd->nd_root.ndm_host), - root_path, MAXPATHLEN) == TRUE) { + nd->nd_root.ndm_path, MAXPATHLEN) == TRUE) { do_bpgetfile = FALSE; do_bpwhoami = FALSE; } @@ -244,53 +251,37 @@ nfs_boot_init(nd, procp) } if (do_bpgetfile) { error = bp_getfile(&bp_sin, "root", &nd->nd_root.ndm_saddr, - nd->nd_root.ndm_host, root_path); + nd->nd_root.ndm_host, nd->nd_root.ndm_path); if (error) { printf("nfs_boot: bootparam get root: %d\n", error); goto failed; } } - - error = get_file_handle(root_path, &nd->nd_root); - if (error) { - printf("nfs_boot: get_file_handle() root failed, %d\n", error); - goto failed; - } #if !defined(NO_MOUNT_PRIVATE) if (do_bpgetfile) { /* get private path */ - char * private_path = NULL; - - MALLOC(private_path, char *, MAXPATHLEN, M_TEMP, M_WAITOK); + MALLOC_ZONE(nd->nd_private.ndm_path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK); error = bp_getfile(&bp_sin, "private", &nd->nd_private.ndm_saddr, - nd->nd_private.ndm_host, private_path); + nd->nd_private.ndm_host, + nd->nd_private.ndm_path); if (!error) { char * check_path = NULL; - MALLOC(check_path, char *, MAXPATHLEN, M_TEMP, M_WAITOK); - sprintf(check_path, "%s/private", root_path); + MALLOC_ZONE(check_path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK); + snprintf(check_path, MAXPATHLEN, "%s/private", nd->nd_root.ndm_path); if ((nd->nd_root.ndm_saddr.sin_addr.s_addr == nd->nd_private.ndm_saddr.sin_addr.s_addr) - && (strcmp(check_path, private_path) == 0)) { + && (strcmp(check_path, nd->nd_private.ndm_path) == 0)) { /* private path is prefix of root path, don't mount */ nd->nd_private.ndm_saddr.sin_addr.s_addr = 0; } - else { - error = get_file_handle(private_path, - &nd->nd_private); - if (error) { - printf("nfs_boot: get_file_handle() private failed, %d\n", error); - goto failed; - } - } - _FREE(check_path, M_TEMP); + FREE_ZONE(check_path, MAXPATHLEN, M_NAMEI); } else { /* private key not defined, don't mount */ nd->nd_private.ndm_saddr.sin_addr.s_addr = 0; } - _FREE(private_path, M_TEMP); } else { error = 0; @@ -298,14 +289,51 @@ nfs_boot_init(nd, procp) #endif NO_MOUNT_PRIVATE failed: thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); - _FREE(root_path, M_TEMP); + return (error); +} + +/* + * Called with a partially initialized nfs_diskless struct + * with file handles to be filled in. + */ +int +nfs_boot_getfh(nd, procp, v3) + struct nfs_diskless *nd; + struct proc *procp; + int v3; +{ + int error = 0; + + thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); + + nd->nd_root.ndm_nfsv3 = v3; + error = get_file_handle(&nd->nd_root); + if (error) { + printf("nfs_boot: get_file_handle(v%d) root failed, %d\n", + v3 ? 3 : 2, error); + goto failed; + } + +#if !defined(NO_MOUNT_PRIVATE) + if (nd->nd_private.ndm_saddr.sin_addr.s_addr) { + /* get private file handle */ + nd->nd_private.ndm_nfsv3 = v3; + error = get_file_handle(&nd->nd_private); + if (error) { + printf("nfs_boot: get_file_handle(v%d) private failed, %d\n", + v3 ? 3 : 2, error); + goto failed; + } + } +#endif NO_MOUNT_PRIVATE + failed: + thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); return (error); } static int -get_file_handle(pathname, ndmntp) - char *pathname; /* path on server */ - struct nfs_dlmount *ndmntp; /* output */ +get_file_handle(ndmntp) + struct nfs_dlmount *ndmntp; { char *sp, *dp, *endp; int error; @@ -314,7 +342,8 @@ get_file_handle(pathname, ndmntp) * Get file handle for "key" (root or swap) * using RPC to mountd/mount */ - error = md_mount(&ndmntp->ndm_saddr, pathname, ndmntp->ndm_fh); + error = md_mount(&ndmntp->ndm_saddr, ndmntp->ndm_path, ndmntp->ndm_nfsv3, + ndmntp->ndm_fh, &ndmntp->ndm_fhlen); if (error) return (error); @@ -323,7 +352,7 @@ get_file_handle(pathname, ndmntp) endp = dp + MNAMELEN - 1; dp += strlen(dp); *dp++ = ':'; - for (sp = pathname; *sp && dp < endp;) + for (sp = ndmntp->ndm_path; *sp && dp < endp;) *dp++ = *sp++; *dp = '\0'; return (0); @@ -647,22 +676,25 @@ out: * Also, sets sin->sin_port to the NFS service port. */ static int -md_mount(mdsin, path, fhp) +md_mount(mdsin, path, v3, fhp, fhlenp) struct sockaddr_in *mdsin; /* mountd server address */ char *path; + int v3; u_char *fhp; + u_long *fhlenp; { /* The RPC structures */ struct rpc_string *str; struct rdata { u_long errno; - u_char fh[NFSX_V2FH]; + u_char data[NFSX_V3FHMAX + sizeof(u_long)]; } *rdata; struct mbuf *m; int error, mlen, slen; + int mntversion = v3 ? RPCMNT_VER3 : RPCMNT_VER1; /* Get port number for MOUNTD. */ - error = krpc_portmap(mdsin, RPCPROG_MNT, RPCMNT_VER1, + error = krpc_portmap(mdsin, RPCPROG_MNT, mntversion, &mdsin->sin_port); if (error) return error; @@ -677,22 +709,43 @@ md_mount(mdsin, path, fhp) bcopy(path, str->data, slen); /* Do RPC to mountd. */ - error = krpc_call(mdsin, RPCPROG_MNT, RPCMNT_VER1, + error = krpc_call(mdsin, RPCPROG_MNT, mntversion, RPCMNT_MOUNT, &m, NULL); if (error) return error; /* message already freed */ + /* + * the reply must be long enough to hold the errno plus either of: + * + a v2 filehandle + * + a v3 filehandle length + a v3 filehandle + */ mlen = m->m_len; - if (mlen < sizeof(*rdata)) + if (mlen < sizeof(u_long)) goto bad; rdata = mtod(m, struct rdata *); error = ntohl(rdata->errno); if (error) - goto bad; - bcopy(rdata->fh, fhp, NFSX_V2FH); + goto out; + if (v3) { + u_long fhlen; + u_char *fh; + if (mlen < sizeof(u_long)*2) + goto bad; + fhlen = ntohl(*(u_long*)rdata->data); + fh = rdata->data + sizeof(u_long); + if (mlen < (sizeof(u_long)*2 + fhlen)) + goto bad; + bcopy(fh, fhp, fhlen); + *fhlenp = fhlen; + } else { + if (mlen < (sizeof(u_long) + NFSX_V2FH)) + goto bad; + bcopy(rdata->data, fhp, NFSX_V2FH); + *fhlenp = NFSX_V2FH; + } /* Set port number for NFS use. */ - error = krpc_portmap(mdsin, NFS_PROG, NFS_VER2, + error = krpc_portmap(mdsin, NFS_PROG, v3 ? NFS_VER3 : NFS_VER2, &mdsin->sin_port); goto out; diff --git a/bsd/nfs/nfs_vfsops.c b/bsd/nfs/nfs_vfsops.c index 44faf37c5..7e852dde9 100644 --- a/bsd/nfs/nfs_vfsops.c +++ b/bsd/nfs/nfs_vfsops.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -163,34 +163,6 @@ struct vfsops nfs_vfsops = { VFS_SET(nfs_vfsops, nfs, MOUNT_NFS, VFCF_NETWORK); #endif -/* - * This structure must be filled in by a primary bootstrap or bootstrap - * server for a diskless/dataless machine. It is initialized below just - * to ensure that it is allocated to initialized data (.data not .bss). - */ -struct nfs_diskless nfs_diskless = { 0 }; -int nfs_diskless_valid = 0; - -/* XXX CSM 11/25/97 Upgrade sysctl.h someday */ -#ifdef notyet -SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD, - &nfs_diskless_valid, 0, ""); - -SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD, - nfs_diskless.root_hostnam, 0, ""); - -SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD, - &nfs_diskless.root_saddr, sizeof nfs_diskless.root_saddr, - "%Ssockaddr_in", ""); - -SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_swappath, CTLFLAG_RD, - nfs_diskless.swap_hostnam, 0, ""); - -SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_swapaddr, CTLFLAG_RD, - &nfs_diskless.swap_saddr, sizeof nfs_diskless.swap_saddr, - "%Ssockaddr_in",""); -#endif - void nfsargs_ntoh __P((struct nfs_args *)); static int @@ -413,6 +385,7 @@ nfs_mountroot() struct mount *mppriv; struct vnode *vppriv; #endif /* NO_MOUNT_PRIVATE */ + int v3; procp = current_proc(); /* XXX */ @@ -427,6 +400,20 @@ nfs_mountroot() panic("nfs_boot_init failed with %d\n", error); } + /* try NFSv3 first, if that fails then try NFSv2 */ + v3 = 1; + +tryagain: + error = nfs_boot_getfh(&nd, procp, v3); + if (error) { + if (v3) { + printf("nfs_boot_getfh(v3) failed with %d, trying v2...\n", error); + v3 = 0; + goto tryagain; + } + panic("nfs_boot_getfh(v2) failed with %d\n", error); + } + /* * Create the root mount point. */ @@ -435,7 +422,12 @@ nfs_mountroot() #else if (error = nfs_mount_diskless(&nd.nd_root, "/", NULL, &vp, &mp)) { #endif /* NO_MOUNT_PRIVATE */ - panic("nfs_mount_diskless failed with %d\n", error); + if (v3) { + printf("nfs_mount_diskless(v3) failed with %d, trying v2...\n", error); + v3 = 0; + goto tryagain; + } + panic("nfs_mount_diskless root failed with %d\n", error); } printf("root on %s\n", (char *)&nd.nd_root.ndm_host); @@ -450,7 +442,7 @@ nfs_mountroot() error = nfs_mount_diskless_private(&nd.nd_private, "/private", NULL, &vppriv, &mppriv); if (error) { - panic("nfs_mount_diskless failed with %d\n", error); + panic("nfs_mount_diskless private failed with %d\n", error); } printf("private on %s\n", (char *)&nd.nd_private.ndm_host); @@ -462,6 +454,11 @@ nfs_mountroot() #endif /* NO_MOUNT_PRIVATE */ + if (nd.nd_root.ndm_path) + FREE_ZONE(nd.nd_root.ndm_path, MAXPATHLEN, M_NAMEI); + if (nd.nd_private.ndm_path) + FREE_ZONE(nd.nd_private.ndm_path, MAXPATHLEN, M_NAMEI); + /* Get root attributes (for the time). */ error = VOP_GETATTR(vp, &attr, procp->p_ucred, procp); if (error) panic("nfs_mountroot: getattr for root"); @@ -501,9 +498,11 @@ nfs_mount_diskless(ndmntp, mntname, mntflag, vpp, mpp) args.addrlen = args.addr->sa_len; args.sotype = SOCK_DGRAM; args.fh = ndmntp->ndm_fh; - args.fhsize = NFSX_V2FH; /* need to try v3, then v2 */ + args.fhsize = ndmntp->ndm_fhlen; args.hostname = ndmntp->ndm_host; args.flags = NFSMNT_RESVPORT; + if (ndmntp->ndm_nfsv3) + args.flags |= NFSMNT_NFSV3; MGET(m, M_DONTWAIT, MT_SONAME); bcopy((caddr_t)args.addr, mtod(m, caddr_t), @@ -631,9 +630,11 @@ nfs_mount_diskless_private(ndmntp, mntname, mntflag, vpp, mpp) args.addrlen = args.addr->sa_len; args.sotype = SOCK_DGRAM; args.fh = ndmntp->ndm_fh; - args.fhsize = NFSX_V2FH; + args.fhsize = ndmntp->ndm_fhlen; args.hostname = ndmntp->ndm_host; args.flags = NFSMNT_RESVPORT; + if (ndmntp->ndm_nfsv3) + args.flags |= NFSMNT_NFSV3; MGET(m, M_DONTWAIT, MT_SONAME); bcopy((caddr_t)args.addr, mtod(m, caddr_t), diff --git a/bsd/nfs/nfsdiskless.h b/bsd/nfs/nfsdiskless.h index 59f987e22..3fa123d7f 100644 --- a/bsd/nfs/nfsdiskless.h +++ b/bsd/nfs/nfsdiskless.h @@ -109,7 +109,10 @@ struct nfsv3_diskless { struct nfs_dlmount { struct sockaddr_in ndm_saddr; /* Address of file server */ char ndm_host[MNAMELEN]; /* Host name for mount pt */ - u_char ndm_fh[NFSX_V2FH]; /* The file's file handle */ + char *ndm_path; /* path name for mount pt */ + u_long ndm_nfsv3; /* NFSv3 or NFSv2? */ + u_long ndm_fhlen; /* length of file handle */ + u_char ndm_fh[NFSX_V3FHMAX]; /* The file's file handle */ }; /* diff --git a/bsd/nfs/rpcv2.h b/bsd/nfs/rpcv2.h index d8a2618fe..d7a7a7df3 100644 --- a/bsd/nfs/rpcv2.h +++ b/bsd/nfs/rpcv2.h @@ -99,6 +99,7 @@ #define RPC_PROGMISMATCH 2 #define RPC_PROCUNAVAIL 3 #define RPC_GARBAGE 4 /* I like this one */ +#define RPC_SYSTEM_ERR 5 #define RPC_MISMATCH 0 #define RPC_AUTHERR 1 diff --git a/bsd/sys/sysctl.h b/bsd/sys/sysctl.h index 300072522..70e649306 100644 --- a/bsd/sys/sysctl.h +++ b/bsd/sys/sysctl.h @@ -495,7 +495,8 @@ struct kinfo_proc { #define HW_L2CACHESIZE 20 /* int: L2 Cache Size in Bytes */ #define HW_L3SETTINGS 21 /* int: L3 Cache Settings */ #define HW_L3CACHESIZE 22 /* int: L3 Cache Size in Bytes */ -#define HW_MAXID 23 /* number of valid hw ids */ +#define HW_TB_FREQ 23 /* int: Bus Frequency */ +#define HW_MAXID 24 /* number of valid hw ids */ #define CTL_HW_NAMES { \ { 0, 0 }, \ @@ -520,7 +521,8 @@ struct kinfo_proc { { "l2settings", CTLTYPE_INT }, \ { "l2cachesize", CTLTYPE_INT }, \ { "l3settings", CTLTYPE_INT }, \ - { "l3cachesize", CTLTYPE_INT } \ + { "l3cachesize", CTLTYPE_INT }, \ + { "tbfrequency", CTLTYPE_INT } \ } /* diff --git a/config/System.kext/Contents/Info.plist b/config/System.kext/Contents/Info.plist index cd407ca27..de657ff35 100644 --- a/config/System.kext/Contents/Info.plist +++ b/config/System.kext/Contents/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - System Resource Pseudoextension, Apple Computer Inc, 6.3 + System Resource Pseudoextension, Apple Computer Inc, 6.4 CFBundleIdentifier com.apple.kernel CFBundleInfoDictionaryVersion @@ -15,13 +15,13 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 6.3 + 6.4 CFBundleSignature ???? CFBundleVersion - 6.3 + 6.4 OSBundleCompatibleVersion - 6.3 + 6.4 OSBundleRequired Root OSKernelResource diff --git a/config/System.kext/Contents/PlugIns/AppleNMI.kext/Contents/Info.plist b/config/System.kext/Contents/PlugIns/AppleNMI.kext/Contents/Info.plist index ce1ba7c85..f6652f8df 100644 --- a/config/System.kext/Contents/PlugIns/AppleNMI.kext/Contents/Info.plist +++ b/config/System.kext/Contents/PlugIns/AppleNMI.kext/Contents/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - AppleNMI Pseudoextension, Apple Computer Inc, 6.3 + AppleNMI Pseudoextension, Apple Computer Inc, 6.4 CFBundleIdentifier com.apple.driver.AppleNMI CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 6.3 + 6.4 CFBundleSignature ???? CFBundleVersion - 6.3 + 6.4 OSBundleRequired Root OSKernelResource diff --git a/config/System.kext/Contents/PlugIns/ApplePlatformFamily.kext/Contents/Info.plist b/config/System.kext/Contents/PlugIns/ApplePlatformFamily.kext/Contents/Info.plist index 521aaca3f..3813bf303 100644 --- a/config/System.kext/Contents/PlugIns/ApplePlatformFamily.kext/Contents/Info.plist +++ b/config/System.kext/Contents/PlugIns/ApplePlatformFamily.kext/Contents/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - Apple Platform Family Pseudoextension, Apple Computer Inc, 6.3 + Apple Platform Family Pseudoextension, Apple Computer Inc, 6.4 CFBundleIdentifier com.apple.iokit.ApplePlatformFamily CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 6.3 + 6.4 CFBundleSignature ???? CFBundleVersion - 6.3 + 6.4 OSBundleCompatibleVersion 1.0 OSBundleRequired diff --git a/config/System.kext/Contents/PlugIns/BSDKernel.kext/Contents/Info.plist b/config/System.kext/Contents/PlugIns/BSDKernel.kext/Contents/Info.plist index 8c07bcd49..62fae78b3 100644 --- a/config/System.kext/Contents/PlugIns/BSDKernel.kext/Contents/Info.plist +++ b/config/System.kext/Contents/PlugIns/BSDKernel.kext/Contents/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - BSD Kernel Pseudoextension, Apple Computer Inc, 6.3 + BSD Kernel Pseudoextension, Apple Computer Inc, 6.4 CFBundleIdentifier com.apple.kernel.bsd CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 6.3 + 6.4 CFBundleSignature ???? CFBundleVersion - 6.3 + 6.4 OSBundleCompatibleVersion 1.1 OSBundleRequired diff --git a/config/System.kext/Contents/PlugIns/IOADBFamily.kext/Contents/Info.plist b/config/System.kext/Contents/PlugIns/IOADBFamily.kext/Contents/Info.plist index b22bf9e63..c374e45c1 100644 --- a/config/System.kext/Contents/PlugIns/IOADBFamily.kext/Contents/Info.plist +++ b/config/System.kext/Contents/PlugIns/IOADBFamily.kext/Contents/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - ADB Family Pseudoextension, Apple Computer Inc, 6.3 + ADB Family Pseudoextension, Apple Computer Inc, 6.4 CFBundleIdentifier com.apple.iokit.IOADBFamily CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 6.3 + 6.4 CFBundleSignature ???? CFBundleVersion - 6.3 + 6.4 OSBundleCompatibleVersion 1.0.0b1 OSBundleRequired diff --git a/config/System.kext/Contents/PlugIns/IOKit.kext/Contents/Info.plist b/config/System.kext/Contents/PlugIns/IOKit.kext/Contents/Info.plist index eeaa1ed63..8e99c49eb 100644 --- a/config/System.kext/Contents/PlugIns/IOKit.kext/Contents/Info.plist +++ b/config/System.kext/Contents/PlugIns/IOKit.kext/Contents/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - I/O Kit Pseudoextension, Apple Computer Inc, 6.3 + I/O Kit Pseudoextension, Apple Computer Inc, 6.4 CFBundleIdentifier com.apple.kernel.iokit CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 6.3 + 6.4 CFBundleSignature ???? CFBundleVersion - 6.3 + 6.4 OSBundleCompatibleVersion 1.0.0b1 OSBundleRequired diff --git a/config/System.kext/Contents/PlugIns/IONVRAMFamily.kext/Contents/Info.plist b/config/System.kext/Contents/PlugIns/IONVRAMFamily.kext/Contents/Info.plist index 3fa274ee1..95b388ddd 100644 --- a/config/System.kext/Contents/PlugIns/IONVRAMFamily.kext/Contents/Info.plist +++ b/config/System.kext/Contents/PlugIns/IONVRAMFamily.kext/Contents/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - AppleNMI Pseudoextension, Apple Computer Inc, 6.3 + AppleNMI Pseudoextension, Apple Computer Inc, 6.4 CFBundleIdentifier com.apple.iokit.IONVRAMFamily CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 6.3 + 6.4 CFBundleSignature ???? CFBundleVersion - 6.3 + 6.4 OSBundleCompatibleVersion 1.1 OSBundleRequired diff --git a/config/System.kext/Contents/PlugIns/IOSystemManagement.kext/Contents/Info.plist b/config/System.kext/Contents/PlugIns/IOSystemManagement.kext/Contents/Info.plist index 0e09af808..6dbf1ab02 100644 --- a/config/System.kext/Contents/PlugIns/IOSystemManagement.kext/Contents/Info.plist +++ b/config/System.kext/Contents/PlugIns/IOSystemManagement.kext/Contents/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - System Management Pseudoextension, Apple Computer Inc, 6.3 + System Management Pseudoextension, Apple Computer Inc, 6.4 CFBundleIdentifier com.apple.iokit.IOSystemManagementFamily CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 6.3 + 6.4 CFBundleSignature ???? CFBundleVersion - 6.3 + 6.4 OSBundleCompatibleVersion 1.0.0b1 OSBundleRequired diff --git a/config/System.kext/Contents/PlugIns/Libkern.kext/Contents/Info.plist b/config/System.kext/Contents/PlugIns/Libkern.kext/Contents/Info.plist index 5bc3c3aff..c1eaea038 100644 --- a/config/System.kext/Contents/PlugIns/Libkern.kext/Contents/Info.plist +++ b/config/System.kext/Contents/PlugIns/Libkern.kext/Contents/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - Libkern Pseudoextension, Apple Computer Inc, 6.3 + Libkern Pseudoextension, Apple Computer Inc, 6.4 CFBundleIdentifier com.apple.kernel.libkern CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 6.3 + 6.4 CFBundleSignature ???? CFBundleVersion - 6.3 + 6.4 OSBundleCompatibleVersion 1.0.0b1 OSBundleRequired diff --git a/config/System.kext/Contents/PlugIns/Mach.kext/Contents/Info.plist b/config/System.kext/Contents/PlugIns/Mach.kext/Contents/Info.plist index 66d7a0f49..8a9bf2ce2 100644 --- a/config/System.kext/Contents/PlugIns/Mach.kext/Contents/Info.plist +++ b/config/System.kext/Contents/PlugIns/Mach.kext/Contents/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - Mach Kernel Pseudoextension, Apple Computer Inc, 6.3 + Mach Kernel Pseudoextension, Apple Computer Inc, 6.4 CFBundleIdentifier com.apple.kernel.mach CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 6.3 + 6.4 CFBundleSignature ???? CFBundleVersion - 6.3 + 6.4 OSBundleCompatibleVersion 1.0.0b1 OSBundleRequired diff --git a/iokit/IOKit/IOService.h b/iokit/IOKit/IOService.h index 4e7111324..334fe25ff 100644 --- a/iokit/IOKit/IOService.h +++ b/iokit/IOKit/IOService.h @@ -1835,6 +1835,7 @@ private: bool responseValid ( unsigned long x ); IOReturn allowCancelCommon ( void ); void computeDesiredState ( void ); + void rebuildChildClampBits ( void ); }; #endif /* ! _IOKIT_IOSERVICE_H */ diff --git a/iokit/Kernel/IOCPU.cpp b/iokit/Kernel/IOCPU.cpp index 750bc5fbd..74be14309 100644 --- a/iokit/Kernel/IOCPU.cpp +++ b/iokit/Kernel/IOCPU.cpp @@ -142,7 +142,7 @@ void IOCPU::initCPUs(void) bool IOCPU::start(IOService *provider) { - OSData *busFrequency, *cpuFrequency, *decFrequency; + OSData *busFrequency, *cpuFrequency, *timebaseFrequency; if (!super::start(provider)) return false; @@ -156,13 +156,13 @@ bool IOCPU::start(IOService *provider) // Correct the bus, cpu and dec frequencies in the device tree. busFrequency = OSData::withBytesNoCopy((void *)&gPEClockFrequencyInfo.bus_clock_rate_hz, 4); cpuFrequency = OSData::withBytesNoCopy((void *)&gPEClockFrequencyInfo.cpu_clock_rate_hz, 4); - decFrequency = OSData::withBytesNoCopy((void *)&gPEClockFrequencyInfo.dec_clock_rate_hz, 4); + timebaseFrequency = OSData::withBytesNoCopy((void *)&gPEClockFrequencyInfo.timebase_frequency_hz, 4); provider->setProperty("bus-frequency", busFrequency); provider->setProperty("clock-frequency", cpuFrequency); - provider->setProperty("timebase-frequency", decFrequency); + provider->setProperty("timebase-frequency", timebaseFrequency); busFrequency->release(); cpuFrequency->release(); - decFrequency->release(); + timebaseFrequency->release(); setProperty("IOCPUID", (UInt32)this, 32); diff --git a/iokit/Kernel/IOMemoryDescriptor.cpp b/iokit/Kernel/IOMemoryDescriptor.cpp index 20b05f3e1..70eb479b7 100644 --- a/iokit/Kernel/IOMemoryDescriptor.cpp +++ b/iokit/Kernel/IOMemoryDescriptor.cpp @@ -1736,7 +1736,7 @@ IOReturn IOMemoryDescriptor::doUnmap( addressMap, logical, length ); #endif - if( (addressMap == kernel_map) || (addressMap == get_task_map(current_task()))) { + if( true /* && (addressMap == kernel_map) || (addressMap == get_task_map(current_task()))*/) { if( _memEntry && (addressMap == kernel_map) && (kIOMemoryRequiresWire & _flags)) addressMap = IOPageableMapForAddress( logical ); diff --git a/iokit/Kernel/IOServicePM.cpp b/iokit/Kernel/IOServicePM.cpp index 0f381dbfb..ddc3e0fef 100644 --- a/iokit/Kernel/IOServicePM.cpp +++ b/iokit/Kernel/IOServicePM.cpp @@ -633,7 +633,7 @@ IOReturn IOService::removePowerChild ( IOPowerConnection * theNub ) } } } - + theNub->release(); if ( (pm_vars->theControllingDriver == NULL) || // if not fully initialized @@ -642,6 +642,10 @@ IOReturn IOService::removePowerChild ( IOPowerConnection * theNub ) return IOPMNoErr; // we can do no more } + // Perhaps the departing child was holding up idle or system sleep - we need to re-evaluate our + // childrens' requests. Clear and re-calculate our kIOPMChildClamp and kIOPMChildClamp2 bits. + rebuildChildClampBits(); + computeDesiredState(); // this may be different now changeState(); // change state if we can now tolerate lower power @@ -1082,6 +1086,54 @@ void IOService::setParentInfo ( IOPMPowerFlags newPowerStateFlags, IOPowerConnec IOLockUnlock(pm_vars->parentLock); } +//********************************************************************************* +// rebuildChildClampBits +// +// The ChildClamp bits (kIOPMChildClamp & kIOPMChildClamp2) in our capabilityFlags +// indicate that one of our children (or grandchildren or great-grandchildren or ...) +// doesn't support idle or system sleep in its current state. Since we don't track the +// origin of each bit, every time any child changes state we have to clear these bits +// and rebuild them. +//********************************************************************************* + +void IOService::rebuildChildClampBits(void) +{ + unsigned long i; + OSIterator * iter; + OSObject * next; + IOPowerConnection * connection; + + + // A child's desires has changed. We need to rebuild the child-clamp bits in our + // power state array. Start by clearing the bits in each power state. + + for ( i = 0; i < pm_vars->theNumberOfPowerStates; i++ ) { + pm_vars->thePowerStates[i].capabilityFlags &= ~(kIOPMChildClamp | kIOPMChildClamp2); + } + + // Now loop through the children. When we encounter the calling child, save + // the computed state as this child's desire. And while we're at it, set the ChildClamp bits + // in any of our states that some child has requested with clamp on. + + iter = getChildIterator(gIOPowerPlane); + + if ( iter ) + { + while ( (next = iter->getNextObject()) ) + { + if ( (connection = OSDynamicCast(IOPowerConnection,next)) ) + { + if ( connection->getPreventIdleSleepFlag() ) + pm_vars->thePowerStates[connection->getDesiredDomainState()].capabilityFlags |= kIOPMChildClamp; + if ( connection->getPreventSystemSleepFlag() ) + pm_vars->thePowerStates[connection->getDesiredDomainState()].capabilityFlags |= kIOPMChildClamp2; + } + } + iter->release(); + } + +} + //********************************************************************************* // requestPowerDomainState @@ -1166,17 +1218,8 @@ IOReturn IOService::requestPowerDomainState ( IOPMPowerFlags desiredState, IOPow IOLockLock(pm_vars->childLock); -// A child's desires has changed. We need to rebuild the child-clamp bits in our -// power state array. Start by clearing the bits in each power state. - - for ( i = 0; i < pm_vars->theNumberOfPowerStates; i++ ) { - pm_vars->thePowerStates[i].capabilityFlags &= ~(kIOPMChildClamp | kIOPMChildClamp2); - } - -// Now loop through the children. When we encounter the calling child, save -// the computed state as this child's desire. And while we're at it, set the ChildClamp bits -// in any of our states that some child has requested with clamp on. - + // Now loop through the children. When we encounter the calling child, save + // the computed state as this child's desire. iter = getChildIterator(gIOPowerPlane); if ( iter ) { @@ -1188,16 +1231,14 @@ IOReturn IOService::requestPowerDomainState ( IOPMPowerFlags desiredState, IOPow connection->setPreventSystemSleepFlag(desiredState & kIOPMPreventSystemSleep); connection->setChildHasRequestedPower(); } - if ( connection->getPreventIdleSleepFlag() ) { - pm_vars->thePowerStates[connection->getDesiredDomainState()].capabilityFlags |= kIOPMChildClamp; - } - if ( connection->getPreventSystemSleepFlag() ) { - pm_vars->thePowerStates[connection->getDesiredDomainState()].capabilityFlags |= kIOPMChildClamp2; - } } } iter->release(); } + + // Since a child's power requirements may have changed, clear and rebuild + // kIOPMChildClamp and kIOPMChildClamp2 (idle and system sleep clamps) + rebuildChildClampBits(); IOLockUnlock(pm_vars->childLock); @@ -3224,8 +3265,11 @@ IOReturn IOService::ask_parent ( unsigned long requestedState ) ourRequest |= kIOPMPreventSystemSleep; } - if ( priv->previousRequest == ourRequest ) { // is this a new desire? - return IOPMNoErr; // no, the parent knows already, just return + // is this a new desire? + if ( priv->previousRequest == ourRequest ) + { + // no, the parent knows already, just return + return IOPMNoErr; } if ( priv->we_are_root ) { diff --git a/iokit/KernelConfigTables.cpp b/iokit/KernelConfigTables.cpp index ce09432b7..741d8c448 100644 --- a/iokit/KernelConfigTables.cpp +++ b/iokit/KernelConfigTables.cpp @@ -28,16 +28,16 @@ */ const char * gIOKernelKmods = "{ - 'com.apple.kernel' = '6.3'; - 'com.apple.kernel.bsd' = '6.3'; - 'com.apple.kernel.iokit' = '6.3'; - 'com.apple.kernel.libkern' = '6.3'; - 'com.apple.kernel.mach' = '6.3'; - 'com.apple.iokit.IOADBFamily' = '6.3'; - 'com.apple.iokit.IONVRAMFamily' = '6.3'; - 'com.apple.iokit.IOSystemManagementFamily' = '6.3'; - 'com.apple.iokit.ApplePlatformFamily' = '6.3'; - 'com.apple.driver.AppleNMI' = '6.3'; + 'com.apple.kernel' = '6.4'; + 'com.apple.kernel.bsd' = '6.4'; + 'com.apple.kernel.iokit' = '6.4'; + 'com.apple.kernel.libkern' = '6.4'; + 'com.apple.kernel.mach' = '6.4'; + 'com.apple.iokit.IOADBFamily' = '6.4'; + 'com.apple.iokit.IONVRAMFamily' = '6.4'; + 'com.apple.iokit.IOSystemManagementFamily' = '6.4'; + 'com.apple.iokit.ApplePlatformFamily' = '6.4'; + 'com.apple.driver.AppleNMI' = '6.4'; }"; diff --git a/iokit/conf/version.minor b/iokit/conf/version.minor index 00750edc0..b8626c4cf 100644 --- a/iokit/conf/version.minor +++ b/iokit/conf/version.minor @@ -1 +1 @@ -3 +4 diff --git a/libkern/conf/version.minor b/libkern/conf/version.minor index 00750edc0..b8626c4cf 100644 --- a/libkern/conf/version.minor +++ b/libkern/conf/version.minor @@ -1 +1 @@ -3 +4 diff --git a/libsa/conf/version.minor b/libsa/conf/version.minor index 00750edc0..b8626c4cf 100644 --- a/libsa/conf/version.minor +++ b/libsa/conf/version.minor @@ -1 +1 @@ -3 +4 diff --git a/osfmk/conf/kernelversion.minor b/osfmk/conf/kernelversion.minor index 00750edc0..b8626c4cf 100644 --- a/osfmk/conf/kernelversion.minor +++ b/osfmk/conf/kernelversion.minor @@ -1 +1 @@ -3 +4 diff --git a/osfmk/conf/version.minor b/osfmk/conf/version.minor index 00750edc0..b8626c4cf 100644 --- a/osfmk/conf/version.minor +++ b/osfmk/conf/version.minor @@ -1 +1 @@ -3 +4 diff --git a/osfmk/kern/task.c b/osfmk/kern/task.c index ea12d7b39..2621419f9 100644 --- a/osfmk/kern/task.c +++ b/osfmk/kern/task.c @@ -510,6 +510,10 @@ task_deallocate( assert((task->swap_state & TASK_SW_ELIGIBLE) == 0); #endif /* TASK_SWAPPER */ + if(task->dynamic_working_set) + tws_hash_destroy((tws_hash_t)task->dynamic_working_set); + + eml_task_deallocate(task); ipc_task_terminate(task); @@ -708,8 +712,12 @@ task_terminate_internal( shared_region_mapping_dealloc(task->system_shared_region); + /* + * Flush working set here to avoid I/O in reaper thread + */ if(task->dynamic_working_set) - tws_hash_destroy((tws_hash_t)task->dynamic_working_set); + tws_hash_ws_flush((tws_hash_t) + task->dynamic_working_set); /* * We no longer need to guard against being aborted, so restore diff --git a/osfmk/mach/vm_param.h b/osfmk/mach/vm_param.h index aba1ed3ef..7ec383ca2 100644 --- a/osfmk/mach/vm_param.h +++ b/osfmk/mach/vm_param.h @@ -79,7 +79,8 @@ #endif /* KERNEL_PRIVATE */ #include -#include + +#include /* * The machine independent pages are refered to as PAGES. A page @@ -118,25 +119,119 @@ extern int page_shift; #endif /* PAGE_SIZE_FIXED */ #ifndef ASSEMBLER + +/* + * Convert addresses to pages and vice versa. No rounding is used. + * The atop_32 and ptoa_32 macros should not be use on 64 bit types. + * The round_page_64 and trunc_page_64 macros should be used instead. + */ + +#define atop_32(x) ((uint32_t)(x) >> PAGE_SHIFT) +#define ptoa_32(x) ((uint32_t)(x) << PAGE_SHIFT) +#define atop_64(x) ((uint64_t)(x) >> PAGE_SHIFT) +#define ptoa_64(x) ((uint64_t)(x) << PAGE_SHIFT) + /* - * Convert addresses to pages and vice versa. - * No rounding is used. + * While the following block is enabled, the legacy atop and ptoa + * macros will behave correctly. If not, they will generate + * invalid lvalue errors. */ -#define atop(x) (((natural_t)(x)) >> PAGE_SHIFT) -#define ptoa(x) ((vm_offset_t)((x) << PAGE_SHIFT)) +#if 1 +#define atop(x) ((uint32_t)(x) >> PAGE_SHIFT) +#define ptoa(x) ((uint32_t)(x) << PAGE_SHIFT) +#else +#define atop(x) (0UL = 0) +#define ptoa(x) (0UL = 0) +#endif + /* * Round off or truncate to the nearest page. These will work * for either addresses or counts. (i.e. 1 byte rounds to 1 page - * bytes. + * bytes. The round_page_32 and trunc_page_32 macros should not be + * use on 64 bit types. The round_page_64 and trunc_page_64 macros + * should be used instead. + */ + +#define round_page_32(x) (((uint32_t)(x) + PAGE_MASK) & ~((signed)PAGE_MASK)) +#define trunc_page_32(x) ((uint32_t)(x) & ~((signed)PAGE_MASK)) +#define round_page_64(x) (((uint64_t)(x) + PAGE_MASK) & ~((signed)PAGE_MASK)) +#define trunc_page_64(x) ((uint64_t)(x) & ~((signed)PAGE_MASK)) + + +/* + * While the following block is enabled, the legacy round_page + * and trunc_page macros will behave correctly. If not, they will + * generate invalid lvalue errors. */ -#define round_page(x) ((vm_offset_t)((((vm_offset_t)(x)) + PAGE_MASK) & ~PAGE_MASK)) -#define trunc_page(x) ((vm_offset_t)(((vm_offset_t)(x)) & ~PAGE_MASK)) +#if 1 +#define round_page(x) (((uint32_t)(x) + PAGE_MASK) & ~((signed)PAGE_MASK)) +#define trunc_page(x) ((uint32_t)(x) & ~((signed)PAGE_MASK)) +#else +#define round_page(x) (0UL = 0) +#define trunc_page(x) (0UL = 0) +#endif + +/* + * Enable the following block to find uses of xxx_32 macros that should + * be xxx_64. These macros only work in C code, not C++. The resulting + * binaries are not functional. Look for invalid lvalue errors in + * the compiler output. + * + * Enabling the following block will also find use of the xxx_64 macros + * that have been passed pointers. The parameters should be case to an + * unsigned long type first. Look for invalid operands to binary + error + * in the compiler output. + */ -#define round_page_64(x) ((unsigned long long)((((unsigned long long)(x)) + PAGE_MASK_64) & ~PAGE_MASK_64)) -#define trunc_page_64(x) ((unsigned long long)(((unsigned long long)(x)) & ~PAGE_MASK_64)) +#if 0 +#undef atop_32 +#undef ptoa_32 +#undef round_page_32 +#undef trunc_page_32 +#undef atop_64 +#undef ptoa_64 +#undef round_page_64 +#undef trunc_page_64 + +#ifndef __cplusplus + +#define atop_32(x) \ + (__builtin_choose_expr (sizeof(x) != sizeof(uint64_t), \ + (*(long *)0), \ + (0UL)) = 0) + +#define ptoa_32(x) \ + (__builtin_choose_expr (sizeof(x) != sizeof(uint64_t), \ + (*(long *)0), \ + (0UL)) = 0) + +#define round_page_32(x) \ + (__builtin_choose_expr (sizeof(x) != sizeof(uint64_t), \ + (*(long *)0), \ + (0UL)) = 0) + +#define trunc_page_32(x) \ + (__builtin_choose_expr (sizeof(x) != sizeof(uint64_t), \ + (*(long *)0), \ + (0UL)) = 0) +#else + +#define atop_32(x) (0) +#define ptoa_32(x) (0) +#define round_page_32(x) (0) +#define trunc_page_32(x) (0) + +#endif /* ! __cplusplus */ + +#define atop_64(x) ((uint64_t)((x) + (uint8_t *)0)) +#define ptoa_64(x) ((uint64_t)((x) + (uint8_t *)0)) +#define round_page_64(x) ((uint64_t)((x) + (uint8_t *)0)) +#define trunc_page_64(x) ((uint64_t)((x) + (uint8_t *)0)) + +#endif /* * Determine whether an address is page-aligned, or a count is diff --git a/osfmk/ppc/FirmwareC.c b/osfmk/ppc/FirmwareC.c index a8b7355e0..184c86d4a 100644 --- a/osfmk/ppc/FirmwareC.c +++ b/osfmk/ppc/FirmwareC.c @@ -265,11 +265,11 @@ void GratefulDebInit(bootBumbleC *boot_video_info) { /* Initialize the video deb GratefulDebWork[i].GDdepth = boot_video_info->v_depth; GratefulDebWork[i].GDcollgn = nrmlgn; -// RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.bus_clock_rate_hz >> 6; /* (Update every 16th of a second (16 fps) */ - RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.bus_clock_rate_hz >> 5; /* (Update every 8th of a second (8 fps) */ -// RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.bus_clock_rate_hz >> 4; /* (Update every 4th of a second (4 fps) */ -// RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.bus_clock_rate_hz >> 3; /* (Update every 2th of a second (2 fps) */ -// RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.bus_clock_rate_hz >> 2; /* (Update every 1 second (1 fps) */ +// RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 4; /* (Update every 16th of a second (16 fps) */ + RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 3; /* (Update every 8th of a second (8 fps) */ +// RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 2; /* (Update every 4th of a second (4 fps) */ +// RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 1; /* (Update every 2th of a second (2 fps) */ +// RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 0; /* (Update every 1 second (1 fps) */ sync(); diff --git a/osfmk/ppc/cpu.c b/osfmk/ppc/cpu.c index cbfab1860..bf078d591 100644 --- a/osfmk/ppc/cpu.c +++ b/osfmk/ppc/cpu.c @@ -539,10 +539,10 @@ cpu_signal_handler( pproc = &per_proc_info[cpu]; /* Point to our block */ /* - * Since we've been signaled, wait just under 1ms for the signal lock to pass + * Since we've been signaled, wait about 31 ms for the signal lock to pass */ if(!hw_lock_mbits(&pproc->MPsigpStat, (MPsigpMsgp | MPsigpAck), (MPsigpBusy | MPsigpPass), - (MPsigpBusy | MPsigpPass | MPsigpAck), (gPEClockFrequencyInfo.bus_clock_rate_hz >> 7))) { + (MPsigpBusy | MPsigpPass | MPsigpAck), (gPEClockFrequencyInfo.timebase_frequency_hz >> 5))) { panic("cpu_signal_handler: Lock pass timed out\n"); } @@ -710,7 +710,7 @@ cpu_signal( if((busybitset == 0) && (!hw_lock_mbits(&tpproc->MPsigpStat, MPsigpMsgp, 0, MPsigpBusy, - (gPEClockFrequencyInfo.bus_clock_rate_hz >> 13)))) { /* Try to lock the message block with a .5ms timeout */ + (gPEClockFrequencyInfo.timebase_frequency_hz >> 11)))) { /* Try to lock the message block with a .5ms timeout */ mpproc->numSIGPtimo++; /* Account for timeouts */ return KERN_FAILURE; /* Timed out, take your ball and go home... */ } diff --git a/osfmk/vm/task_working_set.c b/osfmk/vm/task_working_set.c index 90859e626..8d96c7deb 100644 --- a/osfmk/vm/task_working_set.c +++ b/osfmk/vm/task_working_set.c @@ -322,7 +322,7 @@ tws_hash_line_clear( } kern_return_t -tws_lookup( +tws_internal_lookup( tws_hash_t tws, vm_object_offset_t offset, vm_object_t object, @@ -341,10 +341,6 @@ tws_lookup( if(object->private) return KERN_SUCCESS; - if(!tws_lock_try(tws)) { - return KERN_FAILURE; - } - index = do_tws_hash(object, offset, tws->number_of_elements, tws->number_of_lines); loop = 0; @@ -357,7 +353,6 @@ tws_lookup( age_of_cache = ((sched_tick - tws->time_of_creation) >> SCHED_TICK_SHIFT); if (age_of_cache > 35) { - tws_unlock(tws); return KERN_OPERATION_TIMED_OUT; } } @@ -370,7 +365,6 @@ tws_lookup( age_of_cache = ((sched_tick - tws->time_of_creation) >> SCHED_TICK_SHIFT); if (age_of_cache > 60) { - tws_unlock(tws); return KERN_OPERATION_TIMED_OUT; } } @@ -385,16 +379,32 @@ tws_lookup( set = cache_ele->element->line/tws->number_of_lines; ele_line = cache_ele->element->line - set; *line = &tws->cache[set][ele_line]; - tws_unlock(tws); return KERN_SUCCESS; } - tws_unlock(tws); return KERN_FAILURE; } +kern_return_t +tws_lookup( + tws_hash_t tws, + vm_object_offset_t offset, + vm_object_t object, + tws_hash_line_t *line) +{ + kern_return_t kr; + + if(!tws_lock_try(tws)) { + return KERN_FAILURE; + } + kr = tws_internal_lookup(tws, + offset, object, line); + tws_unlock(tws); + return kr; +} + kern_return_t tws_expand_working_set( vm_offset_t tws, @@ -1040,6 +1050,10 @@ tws_build_cluster( object_size = object->size; } + if((!tws) || (!tws_lock_try(tws))) { + return; + } + age_of_cache = ((sched_tick - tws->time_of_creation) >> SCHED_TICK_SHIFT); @@ -1145,6 +1159,7 @@ tws_build_cluster( if (*start >= *end) panic("bad clipping occurred\n"); + tws_unlock(tws); return; } } @@ -1153,12 +1168,12 @@ tws_build_cluster( (object_size >= (after + PAGE_SIZE_64))) { if(length >= pre_heat_size) { - if(tws_lookup(tws, after, object, + if(tws_internal_lookup(tws, after, object, &line) != KERN_SUCCESS) { vm_object_offset_t extend; extend = after + PAGE_SIZE_64; - if(tws_lookup(tws, extend, object, + if(tws_internal_lookup(tws, extend, object, &line) != KERN_SUCCESS) { break; } @@ -1212,7 +1227,7 @@ tws_build_cluster( before -= PAGE_SIZE_64; if(length >= pre_heat_size) { - if(tws_lookup(tws, before, object, + if(tws_internal_lookup(tws, before, object, &line) != KERN_SUCCESS) { vm_object_offset_t extend; @@ -1220,7 +1235,7 @@ tws_build_cluster( if (extend == 0) break; extend -= PAGE_SIZE_64; - if(tws_lookup(tws, extend, object, + if(tws_internal_lookup(tws, extend, object, &line) != KERN_SUCCESS) { break; } @@ -1266,6 +1281,7 @@ tws_build_cluster( *start -= PAGE_SIZE_64; length += PAGE_SIZE; } + tws_unlock(tws); } tws_line_signal( @@ -1835,6 +1851,39 @@ tws_read_startup_file( } +void +tws_hash_ws_flush(tws_hash_t tws) { + tws_startup_t scache; + if(tws == NULL) { + return; + } + tws_lock(tws); + if(tws->startup_name != NULL) { + scache = tws_create_startup_list(tws); + if(scache == NULL) { + /* dump the name cache, we'll */ + /* get it next time */ + kfree((vm_offset_t) + tws->startup_name, + tws->startup_name_length); + tws->startup_name = NULL; + tws_unlock(tws); + return; + } + bsd_write_page_cache_file(tws->uid, tws->startup_name, + scache, scache->tws_hash_size, + tws->mod, tws->fid); + kfree((vm_offset_t)scache, + scache->tws_hash_size); + kfree((vm_offset_t) + tws->startup_name, + tws->startup_name_length); + tws->startup_name = NULL; + } + tws_unlock(tws); + return; +} + void tws_hash_destroy(tws_hash_t tws) { diff --git a/osfmk/vm/task_working_set.h b/osfmk/vm/task_working_set.h index 5c9e57f0a..553fa6c8d 100644 --- a/osfmk/vm/task_working_set.h +++ b/osfmk/vm/task_working_set.h @@ -258,6 +258,10 @@ kern_return_t tws_read_startup_file( tws_startup_t startup, vm_offset_t cache_size); +void +tws_hash_ws_flush( + tws_hash_t tws); + #endif /* _VM_TASK_WORKING_SET_H_ */ diff --git a/pexpert/conf/version.minor b/pexpert/conf/version.minor index 00750edc0..b8626c4cf 100644 --- a/pexpert/conf/version.minor +++ b/pexpert/conf/version.minor @@ -1 +1 @@ -3 +4 diff --git a/pexpert/pexpert/pexpert.h b/pexpert/pexpert/pexpert.h index 6078e3c2c..39d1bd98a 100644 --- a/pexpert/pexpert/pexpert.h +++ b/pexpert/pexpert/pexpert.h @@ -74,6 +74,9 @@ struct clock_frequency_info_t { unsigned long bus_to_cpu_rate_den; unsigned long bus_to_dec_rate_num; unsigned long bus_to_dec_rate_den; + unsigned long timebase_frequency_hz; + unsigned long timebase_frequency_num; + unsigned long timebase_frequency_den; }; typedef struct clock_frequency_info_t clock_frequency_info_t; diff --git a/pexpert/ppc/pe_clock_speed.c b/pexpert/ppc/pe_clock_speed.c index 61f6c8dff..53ca445bb 100644 --- a/pexpert/ppc/pe_clock_speed.c +++ b/pexpert/ppc/pe_clock_speed.c @@ -23,7 +23,7 @@ * pe_clock_speed.c - Determine the best guess for the processor and bus * speed buy using the values returned by run_clock_test. * - * (c) Apple Computer, Inc. 1998-2000 + * (c) Apple Computer, Inc. 1998-2002 * * Writen by: Josh de Cesare * @@ -81,10 +81,15 @@ void PE_Determine_Clock_Speeds(unsigned int via_addr, int num_speeds, gPEClockFrequencyInfo.bus_to_dec_rate_num = 1; gPEClockFrequencyInfo.bus_to_dec_rate_den = 4; + // Assume that the timebase frequency is derived from the bus clock. + gPEClockFrequencyInfo.timebase_frequency_num = bus_freq_num; + gPEClockFrequencyInfo.timebase_frequency_den = bus_freq_den * 4; + // Set the truncated numbers in gPEClockFrequencyInfo. gPEClockFrequencyInfo.bus_clock_rate_hz = tmp_bus_speed; gPEClockFrequencyInfo.cpu_clock_rate_hz = tmp_cpu_speed; gPEClockFrequencyInfo.dec_clock_rate_hz = tmp_bus_speed / 4; + gPEClockFrequencyInfo.timebase_frequency_hz = tmp_bus_speed / 4; PE_call_timebase_callback(); } diff --git a/pexpert/ppc/pe_identify_machine.c b/pexpert/ppc/pe_identify_machine.c index 092d1926f..3ff1df2f4 100644 --- a/pexpert/ppc/pe_identify_machine.c +++ b/pexpert/ppc/pe_identify_machine.c @@ -46,7 +46,8 @@ void pe_identify_machine(void) gPEClockFrequencyInfo.bus_clock_rate_hz = 100000000; gPEClockFrequencyInfo.cpu_clock_rate_hz = 300000000; gPEClockFrequencyInfo.dec_clock_rate_hz = 25000000; - + gPEClockFrequencyInfo.timebase_frequency_hz = 25000000; + // Try to get the values from the device tree. if (DTFindEntry("device_type", "cpu", &cpu) == kSuccess) { if (DTGetProperty(cpu, "bus-frequency", @@ -64,11 +65,16 @@ void pe_identify_machine(void) gPEClockFrequencyInfo.cpu_clock_rate_hz = *value; if (DTGetProperty(cpu, "timebase-frequency", - (void **)&value, &size) == kSuccess) + (void **)&value, &size) == kSuccess) { gPEClockFrequencyInfo.dec_clock_rate_hz = *value; + gPEClockFrequencyInfo.timebase_frequency_hz= *value; + } } // Set the num / den pairs form the hz values. + gPEClockFrequencyInfo.timebase_frequency_num = gPEClockFrequencyInfo.timebase_frequency_hz; + gPEClockFrequencyInfo.timebase_frequency_den = 1; + gPEClockFrequencyInfo.bus_clock_rate_num = gPEClockFrequencyInfo.bus_clock_rate_hz; gPEClockFrequencyInfo.bus_clock_rate_den = 1; diff --git a/pexpert/ppc/pe_init.c b/pexpert/ppc/pe_init.c index afffd30bf..476904add 100644 --- a/pexpert/ppc/pe_init.c +++ b/pexpert/ppc/pe_init.c @@ -245,8 +245,8 @@ void PE_call_timebase_callback(void) struct timebase_freq_t timebase_freq; unsigned long num, den, cnt; - num = gPEClockFrequencyInfo.bus_clock_rate_num * gPEClockFrequencyInfo.bus_to_dec_rate_num; - den = gPEClockFrequencyInfo.bus_clock_rate_den * gPEClockFrequencyInfo.bus_to_dec_rate_den; + num = gPEClockFrequencyInfo.timebase_frequency_num; + den = gPEClockFrequencyInfo.timebase_frequency_den; cnt = 2; while (cnt <= den) { -- 2.45.2