From owner-svn-src-user@FreeBSD.ORG Wed Aug 8 04:28:46 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 04B21106566B; Wed, 8 Aug 2012 04:28:46 +0000 (UTC) (envelope-from mjacob@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id DECDE8FC08; Wed, 8 Aug 2012 04:28:45 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q784SjQN042533; Wed, 8 Aug 2012 04:28:45 GMT (envelope-from mjacob@svn.freebsd.org) Received: (from mjacob@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q784SjsT042522; Wed, 8 Aug 2012 04:28:45 GMT (envelope-from mjacob@svn.freebsd.org) Message-Id: <201208080428.q784SjsT042522@svn.freebsd.org> From: Matt Jacob Date: Wed, 8 Aug 2012 04:28:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r239136 - in user/mjacob/sys: amd64/amd64 arm/arm boot/common boot/i386/libi386 boot/i386/loader boot/i386/pmbr boot/pc98/boot2 boot/pc98/btx/btxldr boot/pc98/btx/lib boot/pc98/cdboot b... X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Aug 2012 04:28:46 -0000 Author: mjacob Date: Wed Aug 8 04:28:45 2012 New Revision: 239136 URL: http://svn.freebsd.org/changeset/base/239136 Log: MFC@239135 Added: user/mjacob/sys/boot/common/part.c - copied unchanged from r239135, head/sys/boot/common/part.c user/mjacob/sys/boot/common/part.h - copied unchanged from r239135, head/sys/boot/common/part.h user/mjacob/sys/powerpc/powermac/nvbl.c - copied unchanged from r239135, head/sys/powerpc/powermac/nvbl.c Modified: user/mjacob/sys/amd64/amd64/elf_machdep.c user/mjacob/sys/amd64/amd64/initcpu.c user/mjacob/sys/amd64/amd64/pmap.c user/mjacob/sys/arm/arm/bcopyinout.S user/mjacob/sys/arm/arm/bcopyinout_xscale.S user/mjacob/sys/arm/arm/exception.S user/mjacob/sys/arm/arm/pmap.c user/mjacob/sys/boot/common/Makefile.inc user/mjacob/sys/boot/common/disk.c user/mjacob/sys/boot/common/disk.h user/mjacob/sys/boot/i386/libi386/Makefile user/mjacob/sys/boot/i386/libi386/biosdisk.c user/mjacob/sys/boot/i386/libi386/devicename.c user/mjacob/sys/boot/i386/libi386/libi386.h user/mjacob/sys/boot/i386/loader/Makefile user/mjacob/sys/boot/i386/loader/main.c user/mjacob/sys/boot/i386/pmbr/pmbr.s user/mjacob/sys/boot/pc98/boot2/boot2.c user/mjacob/sys/boot/pc98/btx/btxldr/btxldr.S user/mjacob/sys/boot/pc98/btx/lib/btxcsu.S user/mjacob/sys/boot/pc98/cdboot/cdboot.S user/mjacob/sys/boot/pc98/libpc98/Makefile user/mjacob/sys/boot/userboot/test/test.c user/mjacob/sys/boot/userboot/userboot.h user/mjacob/sys/boot/userboot/userboot/Makefile user/mjacob/sys/boot/userboot/userboot/bootinfo32.c user/mjacob/sys/boot/userboot/userboot/copy.c user/mjacob/sys/boot/userboot/userboot/devicename.c user/mjacob/sys/boot/userboot/userboot/main.c user/mjacob/sys/boot/userboot/userboot/userboot_disk.c user/mjacob/sys/boot/zfs/zfs.c user/mjacob/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c user/mjacob/sys/conf/files.powerpc user/mjacob/sys/conf/kern.post.mk user/mjacob/sys/dev/agp/agp.c user/mjacob/sys/dev/agp/agp_i810.c user/mjacob/sys/dev/aic7xxx/aic79xx_osm.c user/mjacob/sys/dev/aic7xxx/aic_osm_lib.c user/mjacob/sys/dev/ath/ah_osdep.h user/mjacob/sys/dev/ath/ath_hal/ah.h user/mjacob/sys/dev/ath/ath_hal/ah_devid.h user/mjacob/sys/dev/ath/ath_hal/ar5210/ar5210.h user/mjacob/sys/dev/ath/ath_hal/ar5210/ar5210_xmit.c user/mjacob/sys/dev/ath/ath_hal/ar5211/ar5211.h user/mjacob/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c user/mjacob/sys/dev/ath/ath_hal/ar5212/ar5212.h user/mjacob/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c user/mjacob/sys/dev/ath/ath_hal/ar5416/ar5416.h user/mjacob/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c user/mjacob/sys/dev/ath/if_ath_beacon.c user/mjacob/sys/dev/ath/if_ath_rx.c user/mjacob/sys/dev/ath/if_ath_rx_edma.c user/mjacob/sys/dev/ath/if_ath_tx.c user/mjacob/sys/dev/ath/if_athvar.h user/mjacob/sys/dev/bce/if_bce.c user/mjacob/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_provider.c user/mjacob/sys/dev/cxgbe/firmware/t4fw_interface.h user/mjacob/sys/dev/e1000/if_igb.c user/mjacob/sys/dev/esp/ncr53c9x.c user/mjacob/sys/dev/hptiop/hptiop.c user/mjacob/sys/dev/ipmi/ipmi.c user/mjacob/sys/dev/ipmi/ipmivars.h user/mjacob/sys/dev/isp/isp_sbus.c user/mjacob/sys/dev/md/md.c user/mjacob/sys/dev/pci/pci_pci.c user/mjacob/sys/dev/puc/pucdata.c user/mjacob/sys/dev/usb/serial/uftdi.c user/mjacob/sys/dev/usb/serial/uftdi_reg.h user/mjacob/sys/dev/usb/serial/uslcom.c user/mjacob/sys/dev/usb/usbdevs user/mjacob/sys/fs/nfs/nfs_commonport.c user/mjacob/sys/fs/nfsclient/nfs_clbio.c user/mjacob/sys/fs/nwfs/nwfs_io.c user/mjacob/sys/fs/smbfs/smbfs_io.c user/mjacob/sys/fs/tmpfs/tmpfs_subr.c user/mjacob/sys/fs/tmpfs/tmpfs_vnops.c user/mjacob/sys/geom/gate/g_gate.c user/mjacob/sys/geom/geom_io.c user/mjacob/sys/geom/virstor/g_virstor.c user/mjacob/sys/ia64/ia64/pmap.c user/mjacob/sys/kern/kern_clocksource.c user/mjacob/sys/kern/kern_intr.c user/mjacob/sys/kern/kern_proc.c user/mjacob/sys/kern/subr_uio.c user/mjacob/sys/kern/sys_process.c user/mjacob/sys/kern/uipc_syscalls.c user/mjacob/sys/mips/mips/trap.c user/mjacob/sys/net/bpf_zerocopy.c user/mjacob/sys/netinet/ip_dummynet.h user/mjacob/sys/netinet/ipfw/dummynet.txt user/mjacob/sys/netinet/ipfw/ip_dn_io.c user/mjacob/sys/netinet/ipfw/ip_fw_log.c user/mjacob/sys/netinet/sctp_bsd_addr.c user/mjacob/sys/netinet/sctp_input.c user/mjacob/sys/netinet/sctp_pcb.c user/mjacob/sys/netinet/tcp_timer.c user/mjacob/sys/nfsclient/nfs_bio.c user/mjacob/sys/ofed/include/linux/gfp.h user/mjacob/sys/powerpc/conf/GENERIC user/mjacob/sys/powerpc/conf/GENERIC64 user/mjacob/sys/sparc64/include/pmap.h user/mjacob/sys/sparc64/sparc64/pmap.c user/mjacob/sys/sys/bus.h user/mjacob/sys/ufs/ffs/ffs_vnops.c user/mjacob/sys/vm/device_pager.c user/mjacob/sys/vm/sg_pager.c user/mjacob/sys/vm/vm_page.c user/mjacob/sys/vm/vm_page.h user/mjacob/sys/vm/vm_pageout.c user/mjacob/sys/vm/vnode_pager.c user/mjacob/sys/x86/x86/busdma_machdep.c user/mjacob/sys/x86/x86/tsc.c Directory Properties: user/mjacob/sys/ (props changed) user/mjacob/sys/boot/ (props changed) user/mjacob/sys/cddl/contrib/opensolaris/ (props changed) user/mjacob/sys/conf/ (props changed) Modified: user/mjacob/sys/amd64/amd64/elf_machdep.c ============================================================================== --- user/mjacob/sys/amd64/amd64/elf_machdep.c Wed Aug 8 00:20:30 2012 (r239135) +++ user/mjacob/sys/amd64/amd64/elf_machdep.c Wed Aug 8 04:28:45 2012 (r239136) @@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Modified: user/mjacob/sys/amd64/amd64/initcpu.c ============================================================================== --- user/mjacob/sys/amd64/amd64/initcpu.c Wed Aug 8 00:20:30 2012 (r239135) +++ user/mjacob/sys/amd64/amd64/initcpu.c Wed Aug 8 04:28:45 2012 (r239136) @@ -91,11 +91,17 @@ init_amd(void) * * http://support.amd.com/us/Processor_TechDocs/41322_10h_Rev_Gd.pdf * http://support.amd.com/us/Processor_TechDocs/44739_12h_Rev_Gd.pdf + * + * Hypervisors do not provide access to the errata MSR, + * causing #GP exception on attempt to apply the errata. The + * MSR write shall be done on host and persist globally + * anyway, so do not try to do it when under virtualization. */ switch (CPUID_TO_FAMILY(cpu_id)) { case 0x10: case 0x12: - wrmsr(0xc0011029, rdmsr(0xc0011029) | 1); + if ((cpu_feature2 & CPUID2_HV) == 0) + wrmsr(0xc0011029, rdmsr(0xc0011029) | 1); break; } } Modified: user/mjacob/sys/amd64/amd64/pmap.c ============================================================================== --- user/mjacob/sys/amd64/amd64/pmap.c Wed Aug 8 00:20:30 2012 (r239135) +++ user/mjacob/sys/amd64/amd64/pmap.c Wed Aug 8 04:28:45 2012 (r239136) @@ -3468,7 +3468,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, newpte |= PG_G; newpte |= pmap_cache_bits(m->md.pat_mode, 0); - mpte = om = NULL; + mpte = NULL; lock = NULL; rw_rlock(&pvh_global_lock); @@ -3540,12 +3540,6 @@ retry: if (((origpte ^ newpte) & ~(PG_M | PG_A)) == 0) goto unchanged; goto validate; - } else { - /* - * Yes, fall through to validate the new mapping. - */ - if ((origpte & PG_MANAGED) != 0) - om = PHYS_TO_VM_PAGE(opa); } } else { /* @@ -3578,6 +3572,7 @@ validate: opa = origpte & PG_FRAME; if (opa != pa) { if ((origpte & PG_MANAGED) != 0) { + om = PHYS_TO_VM_PAGE(opa); if ((origpte & (PG_M | PG_RW)) == (PG_M | PG_RW)) vm_page_dirty(om); Modified: user/mjacob/sys/arm/arm/bcopyinout.S ============================================================================== --- user/mjacob/sys/arm/arm/bcopyinout.S Wed Aug 8 00:20:30 2012 (r239135) +++ user/mjacob/sys/arm/arm/bcopyinout.S Wed Aug 8 04:28:45 2012 (r239136) @@ -39,6 +39,7 @@ #include "assym.s" #include +#include .L_arm_memcpy: .word _C_LABEL(_arm_memcpy) @@ -310,7 +311,7 @@ ENTRY(copyin) RET .Lcopyfault: - mov r0, #14 /* EFAULT */ + ldr r0, =EFAULT str r5, [r4, #PCB_ONFAULT] RESTORE_REGS Modified: user/mjacob/sys/arm/arm/bcopyinout_xscale.S ============================================================================== --- user/mjacob/sys/arm/arm/bcopyinout_xscale.S Wed Aug 8 00:20:30 2012 (r239135) +++ user/mjacob/sys/arm/arm/bcopyinout_xscale.S Wed Aug 8 04:28:45 2012 (r239136) @@ -108,6 +108,7 @@ ENTRY(copyin) ldmfd sp!, {r10-r11, pc} .Lcopyin_fault: + ldr r0, =EFAULT str r11, [r10, #PCB_ONFAULT] cmp r3, #0x00 ldmgtfd sp!, {r4-r7} /* r3 > 0 Restore r4-r7 */ @@ -559,6 +560,7 @@ ENTRY(copyout) ldmfd sp!, {r10-r11, pc} .Lcopyout_fault: + ldr r0, =EFAULT str r11, [r10, #PCB_ONFAULT] cmp r3, #0x00 ldmgtfd sp!, {r4-r7} /* r3 > 0 Restore r4-r7 */ Modified: user/mjacob/sys/arm/arm/exception.S ============================================================================== --- user/mjacob/sys/arm/arm/exception.S Wed Aug 8 00:20:30 2012 (r239135) +++ user/mjacob/sys/arm/arm/exception.S Wed Aug 8 04:28:45 2012 (r239136) @@ -80,7 +80,10 @@ ASENTRY_NP(swi_entry) PUSHFRAME mov r0, sp /* Pass the frame to any function */ + mov r6, sp /* Backup the stack pointer */ + bic sp, sp, #7 /* Align the stack pointer */ bl _C_LABEL(swi_handler) /* It's a SWI ! */ + mov sp, r6 /* Restore the stack */ DO_AST PULLFRAME Modified: user/mjacob/sys/arm/arm/pmap.c ============================================================================== --- user/mjacob/sys/arm/arm/pmap.c Wed Aug 8 00:20:30 2012 (r239135) +++ user/mjacob/sys/arm/arm/pmap.c Wed Aug 8 04:28:45 2012 (r239136) @@ -154,6 +154,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -165,7 +166,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include Modified: user/mjacob/sys/boot/common/Makefile.inc ============================================================================== --- user/mjacob/sys/boot/common/Makefile.inc Wed Aug 8 00:20:30 2012 (r239135) +++ user/mjacob/sys/boot/common/Makefile.inc Wed Aug 8 04:28:45 2012 (r239136) @@ -1,6 +1,6 @@ # $FreeBSD$ -SRCS+= boot.c commands.c console.c devopen.c disk.c interp.c +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 @@ -24,6 +24,18 @@ SRCS+= load_elf64.c reloc_elf64.c SRCS+= dev_net.c .endif +.if !defined(LOADER_NO_DISK_SUPPORT) +SRCS+= disk.c part.c +CFLAGS+= -DLOADER_DISK_SUPPORT +.if !defined(LOADER_NO_GPT_SUPPORT) +SRCS+= crc32.c +CFLAGS+= -DLOADER_GPT_SUPPORT +.endif +.if !defined(LOADER_NO_MBR_SUPPORT) +CFLAGS+= -DLOADER_MBR_SUPPORT +.endif +.endif + .if defined(HAVE_BCACHE) SRCS+= bcache.c .endif Modified: user/mjacob/sys/boot/common/disk.c ============================================================================== --- user/mjacob/sys/boot/common/disk.c Wed Aug 8 00:20:30 2012 (r239135) +++ user/mjacob/sys/boot/common/disk.c Wed Aug 8 04:28:45 2012 (r239136) @@ -1,5 +1,6 @@ /*- * Copyright (c) 1998 Michael Smith + * Copyright (c) 2012 Andrey V. Elsukov * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,26 +28,11 @@ #include __FBSDID("$FreeBSD$"); -/* - * MBR/GPT partitioned disk device handling. - * - * Ideas and algorithms from: - * - * - NetBSD libi386/biosdisk.c - * - FreeBSD biosboot/disk.c - * - */ - +#include #include - -#include -#include -#include - #include -#include - #include +#include #include "disk.h" @@ -56,53 +42,26 @@ __FBSDID("$FreeBSD$"); # define DEBUG(fmt, args...) #endif -/* - * Search for a slice with the following preferences: - * - * 1: Active FreeBSD slice - * 2: Non-active FreeBSD slice - * 3: Active Linux slice - * 4: non-active Linux slice - * 5: Active FAT/FAT32 slice - * 6: non-active FAT/FAT32 slice - */ -#define PREF_RAWDISK 0 -#define PREF_FBSD_ACT 1 -#define PREF_FBSD 2 -#define PREF_LINUX_ACT 3 -#define PREF_LINUX 4 -#define PREF_DOS_ACT 5 -#define PREF_DOS 6 -#define PREF_NONE 7 - -#ifdef LOADER_GPT_SUPPORT - -struct gpt_part { - int gp_index; - uuid_t gp_type; - uint64_t gp_start; - uint64_t gp_end; +struct open_disk { + struct ptable *table; + off_t mediasize; + u_int sectorsize; }; -static uuid_t efi = GPT_ENT_TYPE_EFI; -static uuid_t freebsd_boot = GPT_ENT_TYPE_FREEBSD_BOOT; -static uuid_t freebsd_ufs = GPT_ENT_TYPE_FREEBSD_UFS; -static uuid_t freebsd_swap = GPT_ENT_TYPE_FREEBSD_SWAP; -static uuid_t freebsd_zfs = GPT_ENT_TYPE_FREEBSD_ZFS; -static uuid_t ms_basic_data = GPT_ENT_TYPE_MS_BASIC_DATA; - -#endif - -#if defined(LOADER_GPT_SUPPORT) || defined(LOADER_MBR_SUPPORT) +struct print_args { + struct disk_devdesc *dev; + const char *prefix; + int verbose; +}; -/* Given a size in 512 byte sectors, convert it to a human-readable number. */ +/* Convert size to a human-readable number. */ static char * -display_size(uint64_t size) +display_size(uint64_t size, u_int sectorsize) { static char buf[80]; char unit; - size /= 2; + size = size * sectorsize / 1024; unit = 'K'; if (size >= 10485760000LL) { size /= 1073741824; @@ -114,687 +73,230 @@ display_size(uint64_t size) size /= 1024; unit = 'M'; } - sprintf(buf, "%.6ld%cB", (long)size, unit); + sprintf(buf, "%ld%cB", (long)size, unit); return (buf); } -#endif - -#ifdef LOADER_MBR_SUPPORT - -static void -disk_checkextended(struct disk_devdesc *dev, - struct dos_partition *slicetab, int slicenum, int *nslicesp) -{ - uint8_t buf[DISK_SECSIZE]; - struct dos_partition *dp; - uint32_t base; - int rc, i, start, end; - - dp = &slicetab[slicenum]; - start = *nslicesp; - - if (dp->dp_size == 0) - goto done; - if (dp->dp_typ != DOSPTYP_EXT) - goto done; - rc = dev->d_dev->dv_strategy(dev, F_READ, dp->dp_start, DISK_SECSIZE, - (char *) buf, NULL); - if (rc) - goto done; - if (buf[0x1fe] != 0x55 || buf[0x1ff] != 0xaa) { - DEBUG("no magic in extended table"); - goto done; - } - base = dp->dp_start; - dp = (struct dos_partition *) &buf[DOSPARTOFF]; - for (i = 0; i < NDOSPART; i++, dp++) { - if (dp->dp_size == 0) - continue; - if (*nslicesp == NEXTDOSPART) - goto done; - dp->dp_start += base; - bcopy(dp, &slicetab[*nslicesp], sizeof(*dp)); - (*nslicesp)++; - } - end = *nslicesp; - - /* - * now, recursively check the slices we just added - */ - for (i = start; i < end; i++) - disk_checkextended(dev, slicetab, i, nslicesp); -done: - return; -} - -static int -disk_readslicetab(struct disk_devdesc *dev, - struct dos_partition **slicetabp, int *nslicesp) -{ - struct dos_partition *slicetab = NULL; - int nslices, i; - int rc; - uint8_t buf[DISK_SECSIZE]; - - /* - * Find the slice in the DOS slice table. - */ - rc = dev->d_dev->dv_strategy(dev, F_READ, 0, DISK_SECSIZE, - (char *) buf, NULL); - if (rc) { - DEBUG("error reading MBR"); - return (rc); - } - - /* - * Check the slice table magic. - */ - if (buf[0x1fe] != 0x55 || buf[0x1ff] != 0xaa) { - DEBUG("no slice table/MBR (no magic)"); - return (rc); - } - - /* - * copy the partition table, then pick up any extended partitions. - */ - slicetab = malloc(NEXTDOSPART * sizeof(struct dos_partition)); - bcopy(buf + DOSPARTOFF, slicetab, - sizeof(struct dos_partition) * NDOSPART); - nslices = NDOSPART; /* extended slices start here */ - for (i = 0; i < NDOSPART; i++) - disk_checkextended(dev, slicetab, i, &nslices); - - *slicetabp = slicetab; - *nslicesp = nslices; - return (0); -} - -/* - * Search for the best MBR slice (typically the first FreeBSD slice). - */ -static int -disk_bestslice(struct dos_partition *slicetab, int nslices) -{ - struct dos_partition *dp; - int pref, preflevel; - int i, prefslice; - - prefslice = 0; - preflevel = PREF_NONE; - - dp = &slicetab[0]; - for (i = 0; i < nslices; i++, dp++) { - switch (dp->dp_typ) { - case DOSPTYP_386BSD: /* FreeBSD */ - pref = dp->dp_flag & 0x80 ? PREF_FBSD_ACT : PREF_FBSD; - break; - - case DOSPTYP_LINUX: - pref = dp->dp_flag & 0x80 ? PREF_LINUX_ACT : PREF_LINUX; - break; - - case 0x01: /* DOS/Windows */ - case 0x04: - case 0x06: - case 0x0b: - case 0x0c: - case 0x0e: - pref = dp->dp_flag & 0x80 ? PREF_DOS_ACT : PREF_DOS; - break; - - default: - pref = PREF_NONE; - } - if (pref < preflevel) { - preflevel = pref; - prefslice = i + 1; - } - } - return (prefslice); -} - static int -disk_openmbr(struct disk_devdesc *dev) -{ - struct dos_partition *slicetab = NULL, *dptr; - int nslices, sector, slice; - int rc; - uint8_t buf[DISK_SECSIZE]; - struct disklabel *lp; - - /* - * Following calculations attempt to determine the correct value - * for dev->d_offset by looking for the slice and partition specified, - * or searching for reasonable defaults. - */ - rc = disk_readslicetab(dev, &slicetab, &nslices); - if (rc) - return (rc); - - /* - * if a slice number was supplied but not found, this is an error. - */ - if (dev->d_slice > 0) { - slice = dev->d_slice - 1; - if (slice >= nslices) { - DEBUG("slice %d not found", slice); - rc = EPART; - goto out; - } - } - - /* - * Check for the historically bogus MBR found on true dedicated disks - */ - if (slicetab[3].dp_typ == DOSPTYP_386BSD && - slicetab[3].dp_start == 0 && slicetab[3].dp_size == 50000) { - sector = 0; - goto unsliced; - } - - /* - * Try to auto-detect the best slice; this should always give - * a slice number - */ - if (dev->d_slice == 0) { - slice = disk_bestslice(slicetab, nslices); - if (slice == -1) { - rc = ENOENT; - goto out; - } - dev->d_slice = slice; - } - - /* - * Accept the supplied slice number unequivocally (we may be looking - * at a DOS partition). - * Note: we number 1-4, offsets are 0-3 - */ - dptr = &slicetab[dev->d_slice - 1]; - sector = dptr->dp_start; - DEBUG("slice entry %d at %d, %d sectors", - dev->d_slice - 1, sector, dptr->dp_size); - -unsliced: - /* - * Now we have the slice offset, look for the partition in the - * disklabel if we have a partition to start with. - * - * XXX we might want to check the label checksum. - */ - if (dev->d_partition < 0) { - /* no partition, must be after the slice */ - DEBUG("opening raw slice"); - dev->d_offset = sector; - rc = 0; - goto out; - } - - rc = dev->d_dev->dv_strategy(dev, F_READ, sector + LABELSECTOR, - DISK_SECSIZE, (char *) buf, NULL); - if (rc) { - DEBUG("error reading disklabel"); - goto out; - } - - lp = (struct disklabel *) buf; - - if (lp->d_magic != DISKMAGIC) { - DEBUG("no disklabel"); - rc = ENOENT; - goto out; - } - if (dev->d_partition >= lp->d_npartitions) { - DEBUG("partition '%c' exceeds partitions in table (a-'%c')", - 'a' + dev->d_partition, - 'a' + lp->d_npartitions); - rc = EPART; - goto out; - } - - dev->d_offset = - lp->d_partitions[dev->d_partition].p_offset - - lp->d_partitions[RAW_PART].p_offset + - sector; - rc = 0; - -out: - if (slicetab) - free(slicetab); - return (rc); -} - -/* - * Print out each valid partition in the disklabel of a FreeBSD slice. - * For size calculations, we assume a 512 byte sector size. - */ -static void -disk_printbsdslice(struct disk_devdesc *dev, daddr_t offset, - char *prefix, int verbose) +ptblread(void *d, void *buf, size_t blocks, off_t offset) { - char line[80]; - char buf[DISK_SECSIZE]; - struct disklabel *lp; - int i, rc, fstype; - - /* read disklabel */ - rc = dev->d_dev->dv_strategy(dev, F_READ, offset + LABELSECTOR, - DISK_SECSIZE, (char *) buf, NULL); - if (rc) - return; - lp =(struct disklabel *)(&buf[0]); - if (lp->d_magic != DISKMAGIC) { - sprintf(line, "%s: FFS bad disklabel\n", prefix); - pager_output(line); - return; - } + struct disk_devdesc *dev; + struct open_disk *od; - /* Print partitions */ - for (i = 0; i < lp->d_npartitions; i++) { - /* - * For each partition, make sure we know what type of fs it - * is. If not, then skip it. - */ - fstype = lp->d_partitions[i].p_fstype; - if (fstype != FS_BSDFFS && - fstype != FS_SWAP && - fstype != FS_VINUM) - continue; - - /* Only print out statistics in verbose mode */ - if (verbose) - sprintf(line, " %s%c: %s %s (%d - %d)\n", - prefix, 'a' + i, - (fstype == FS_SWAP) ? "swap " : - (fstype == FS_VINUM) ? "vinum" : - "FFS ", - display_size(lp->d_partitions[i].p_size), - lp->d_partitions[i].p_offset, - (lp->d_partitions[i].p_offset - + lp->d_partitions[i].p_size)); - else - sprintf(line, " %s%c: %s\n", prefix, 'a' + i, - (fstype == FS_SWAP) ? "swap" : - (fstype == FS_VINUM) ? "vinum" : - "FFS"); - pager_output(line); - } + dev = (struct disk_devdesc *)d; + od = (struct open_disk *)dev->d_opendata; + return (dev->d_dev->dv_strategy(dev, F_READ, offset, + blocks * od->sectorsize, (char *)buf, NULL)); } +#define PWIDTH 35 static void -disk_printslice(struct disk_devdesc *dev, int slice, - struct dos_partition *dp, char *prefix, int verbose) +ptable_print(void *arg, const char *pname, const struct ptable_entry *part) { - char stats[80]; + struct print_args *pa, bsd; + struct open_disk *od; + struct ptable *table; char line[80]; - if (verbose) - sprintf(stats, " %s (%d - %d)", display_size(dp->dp_size), - dp->dp_start, dp->dp_start + dp->dp_size); - else - stats[0] = '\0'; - - switch (dp->dp_typ) { - case DOSPTYP_386BSD: - disk_printbsdslice(dev, (daddr_t)dp->dp_start, - prefix, verbose); - return; - case DOSPTYP_LINSWP: - sprintf(line, "%s: Linux swap%s\n", prefix, stats); - break; - case DOSPTYP_LINUX: - /* - * XXX - * read the superblock to confirm this is an ext2fs partition? - */ - sprintf(line, "%s: ext2fs%s\n", prefix, stats); - break; - case 0x00: /* unused partition */ - case DOSPTYP_EXT: - return; - case 0x01: - sprintf(line, "%s: FAT-12%s\n", prefix, stats); - break; - case 0x04: - case 0x06: - case 0x0e: - sprintf(line, "%s: FAT-16%s\n", prefix, stats); - break; - case 0x07: - sprintf(line, "%s: NTFS/HPFS%s\n", prefix, stats); - break; - case 0x0b: - case 0x0c: - sprintf(line, "%s: FAT-32%s\n", prefix, stats); - break; - default: - sprintf(line, "%s: Unknown fs: 0x%x %s\n", prefix, dp->dp_typ, - stats); - } + pa = (struct print_args *)arg; + od = (struct open_disk *)pa->dev->d_opendata; + sprintf(line, " %s%s: %s", pa->prefix, pname, + parttype2str(part->type)); + if (pa->verbose) + sprintf(line, "%-*s%s", PWIDTH, line, + display_size(part->end - part->start + 1, + od->sectorsize)); + strcat(line, "\n"); pager_output(line); -} - -static int -disk_printmbr(struct disk_devdesc *dev, char *prefix, int verbose) -{ - struct dos_partition *slicetab; - int nslices, i; - int rc; - char line[80]; - - rc = disk_readslicetab(dev, &slicetab, &nslices); - if (rc) - return (rc); - for (i = 0; i < nslices; i++) { - sprintf(line, "%ss%d", prefix, i + 1); - disk_printslice(dev, i, &slicetab[i], line, verbose); - } - free(slicetab); - return (0); -} - -#endif - -#ifdef LOADER_GPT_SUPPORT - -static int -disk_readgpt(struct disk_devdesc *dev, struct gpt_part **gptp, int *ngptp) -{ - struct dos_partition *dp; - struct gpt_hdr *hdr; - struct gpt_ent *ent; - struct gpt_part *gptab = NULL; - int entries_per_sec, rc, i, part; - daddr_t lba, elba; - uint8_t gpt[DISK_SECSIZE], tbl[DISK_SECSIZE]; - - /* - * Following calculations attempt to determine the correct value - * for dev->d_offset by looking for the slice and partition specified, - * or searching for reasonable defaults. - */ - rc = 0; - - /* First, read the MBR and see if we have a PMBR. */ - rc = dev->d_dev->dv_strategy(dev, F_READ, 0, DISK_SECSIZE, - (char *) tbl, NULL); - if (rc) { - DEBUG("error reading MBR"); - return (EIO); + if (part->type == PART_FREEBSD) { + /* Open slice with BSD label */ + pa->dev->d_offset = part->start; + table = ptable_open(pa->dev, part->end - part->start + 1, + od->sectorsize, ptblread); + if (table == NULL) + return; + sprintf(line, " %s%s", pa->prefix, pname); + bsd.dev = pa->dev; + bsd.prefix = line; + bsd.verbose = pa->verbose; + ptable_iterate(table, &bsd, ptable_print); + ptable_close(table); } - - /* Check the slice table magic. */ - if (tbl[0x1fe] != 0x55 || tbl[0x1ff] != 0xaa) - return (ENXIO); - - /* Check for GPT slice. */ - part = 0; - dp = (struct dos_partition *)(tbl + DOSPARTOFF); - for (i = 0; i < NDOSPART; i++) { - if (dp[i].dp_typ == 0xee) - part++; - else if ((part != 1) && (dp[i].dp_typ != 0x00)) - return (EINVAL); - } - if (part != 1) - return (EINVAL); - - /* Read primary GPT table header. */ - rc = dev->d_dev->dv_strategy(dev, F_READ, 1, DISK_SECSIZE, - (char *) gpt, NULL); - if (rc) { - DEBUG("error reading GPT header"); - return (EIO); - } - hdr = (struct gpt_hdr *)gpt; - if (bcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig)) != 0 || - hdr->hdr_lba_self != 1 || hdr->hdr_revision < 0x00010000 || - hdr->hdr_entsz < sizeof(*ent) || - DISK_SECSIZE % hdr->hdr_entsz != 0) { - DEBUG("Invalid GPT header\n"); - return (EINVAL); - } - - /* Walk the partition table to count valid partitions. */ - part = 0; - entries_per_sec = DISK_SECSIZE / hdr->hdr_entsz; - elba = hdr->hdr_lba_table + hdr->hdr_entries / entries_per_sec; - for (lba = hdr->hdr_lba_table; lba < elba; lba++) { - rc = dev->d_dev->dv_strategy(dev, F_READ, lba, DISK_SECSIZE, - (char *) tbl, NULL); - if (rc) { - DEBUG("error reading GPT table"); - return (EIO); - } - for (i = 0; i < entries_per_sec; i++) { - ent = (struct gpt_ent *)(tbl + i * hdr->hdr_entsz); - if (uuid_is_nil(&ent->ent_type, NULL) || - ent->ent_lba_start == 0 || - ent->ent_lba_end < ent->ent_lba_start) - continue; - part++; - } - } - - /* Save the important information about all the valid partitions. */ - if (part != 0) { - gptab = malloc(part * sizeof(struct gpt_part)); - part = 0; - for (lba = hdr->hdr_lba_table; lba < elba; lba++) { - rc = dev->d_dev->dv_strategy(dev, F_READ, lba, DISK_SECSIZE, - (char *) tbl, NULL); - if (rc) { - DEBUG("error reading GPT table"); - free(gptab); - return (EIO); - } - for (i = 0; i < entries_per_sec; i++) { - ent = (struct gpt_ent *)(tbl + i * hdr->hdr_entsz); - if (uuid_is_nil(&ent->ent_type, NULL) || - ent->ent_lba_start == 0 || - ent->ent_lba_end < ent->ent_lba_start) - continue; - gptab[part].gp_index = (lba - hdr->hdr_lba_table) * - entries_per_sec + i + 1; - gptab[part].gp_type = ent->ent_type; - gptab[part].gp_start = ent->ent_lba_start; - gptab[part].gp_end = ent->ent_lba_end; - part++; - } - } - } - - *gptp = gptab; - *ngptp = part; - return (0); } +#undef PWIDTH -static struct gpt_part * -disk_bestgpt(struct gpt_part *gpt, int ngpt) +void +disk_print(struct disk_devdesc *dev, char *prefix, int verbose) { - struct gpt_part *gp, *prefpart; - int i, pref, preflevel; - - prefpart = NULL; - preflevel = PREF_NONE; + struct open_disk *od; + struct print_args pa; - gp = gpt; - for (i = 0; i < ngpt; i++, gp++) { - /* Windows. XXX: Also Linux. */ - if (uuid_equal(&gp->gp_type, &ms_basic_data, NULL)) - pref = PREF_DOS; - /* FreeBSD */ - else if (uuid_equal(&gp->gp_type, &freebsd_ufs, NULL) || - uuid_equal(&gp->gp_type, &freebsd_zfs, NULL)) - pref = PREF_FBSD; - else - pref = PREF_NONE; - if (pref < preflevel) { - preflevel = pref; - prefpart = gp; - } - } - return (prefpart); + /* Disk should be opened */ + od = (struct open_disk *)dev->d_opendata; + pa.dev = dev; + pa.prefix = prefix; + pa.verbose = verbose; + ptable_iterate(od->table, &pa, ptable_print); } -static int -disk_opengpt(struct disk_devdesc *dev) +int +disk_open(struct disk_devdesc *dev, off_t mediasize, u_int sectorsize) { - struct gpt_part *gpt = NULL, *gp; - int rc, ngpt, i; + struct open_disk *od; + struct ptable *table; + struct ptable_entry part; + int rc; - rc = disk_readgpt(dev, &gpt, &ngpt); - if (rc) - return (rc); - - /* Is this a request for the whole disk? */ - if (dev->d_slice < 0) { - dev->d_offset = 0; - rc = 0; - goto out; + od = (struct open_disk *)malloc(sizeof(struct open_disk)); + if (od == NULL) { + DEBUG("no memory"); + return (ENOMEM); } - /* - * If a partition number was supplied, then the user is trying to use - * an MBR address rather than a GPT address, so fail. + * While we are reading disk metadata, make sure we do it relative + * to the start of the disk */ - if (dev->d_partition != 0xff) { - rc = ENOENT; + rc = 0; + table = NULL; + dev->d_offset = 0; + dev->d_opendata = od; + od->mediasize = mediasize; + od->sectorsize = sectorsize; + DEBUG("open '%s', unit %d slice %d partition %d", + disk_fmtdev(dev), dev->d_unit, dev->d_slice, dev->d_partition); + + /* Determine disk layout. */ + od->table = ptable_open(dev, mediasize / sectorsize, sectorsize, + ptblread); + if (od->table == NULL) { + DEBUG("Can't read partition table"); + rc = ENXIO; goto out; } - - /* If a slice number was supplied but not found, this is an error. */ - gp = NULL; if (dev->d_slice > 0) { - for (i = 0; i < ngpt; i++) { - if (gpt[i].gp_index == dev->d_slice) { - gp = &gpt[i]; - break; - } - } - if (gp == NULL) { - DEBUG("partition %d not found", dev->d_slice); - rc = ENOENT; + /* Try to get information about partition */ + rc = ptable_getpart(od->table, &part, dev->d_slice); + if (rc != 0) /* Partition doesn't exist */ goto out; - } - } - - /* Try to auto-detect the best partition. */ - if (dev->d_slice == 0) { - gp = disk_bestgpt(gpt, ngpt); - if (gp == NULL) { - rc = ENOENT; + dev->d_offset = part.start; + if (dev->d_partition == -1 || + dev->d_partition == 255) + goto out; /* Nothing more to do */ + + /* Try to read BSD label */ + table = ptable_open(dev, part.end - part.start + 1, + od->sectorsize, ptblread); + if (table == NULL) { + DEBUG("Can't read BSD label"); + rc = ENXIO; goto out; } - dev->d_slice = gp->gp_index; + rc = ptable_getpart(table, &part, dev->d_partition); + if (rc != 0) + goto out; + dev->d_offset += part.start; + } else if (dev->d_slice == 0) { + rc = ptable_getbestpart(od->table, &part); + if (rc != 0) + goto out; + /* Save the slice number of best partition to dev */ + dev->d_slice = part.index; + dev->d_offset = part.start; } - - dev->d_offset = gp->gp_start; - rc = 0; - out: - if (gpt) - free(gpt); + if (table != NULL) + ptable_close(table); + if (rc != 0) { + if (od->table != NULL) + ptable_close(od->table); + free(od); + } return (rc); } -static void -disk_printgptpart(struct disk_devdesc *dev, struct gpt_part *gp, - char *prefix, int verbose) +int +disk_close(struct disk_devdesc *dev) { - char stats[80]; - char line[96]; - - if (verbose) - sprintf(stats, " %s", - display_size(gp->gp_end + 1 - gp->gp_start)); - else - stats[0] = '\0'; - - if (uuid_equal(&gp->gp_type, &efi, NULL)) - sprintf(line, "%s: EFI %s\n", prefix, stats); - else if (uuid_equal(&gp->gp_type, &ms_basic_data, NULL)) - sprintf(line, "%s: FAT/NTFS %s\n", prefix, stats); - else if (uuid_equal(&gp->gp_type, &freebsd_boot, NULL)) - sprintf(line, "%s: FreeBSD boot%s\n", prefix, stats); - else if (uuid_equal(&gp->gp_type, &freebsd_ufs, NULL)) - sprintf(line, "%s: FreeBSD UFS %s\n", prefix, stats); - else if (uuid_equal(&gp->gp_type, &freebsd_zfs, NULL)) - sprintf(line, "%s: FreeBSD ZFS %s\n", prefix, stats); - else if (uuid_equal(&gp->gp_type, &freebsd_swap, NULL)) - sprintf(line, "%s: FreeBSD swap%s\n", prefix, stats); - else - sprintf(line, - "%s: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x%s\n", - prefix, - gp->gp_type.time_low, gp->gp_type.time_mid, - gp->gp_type.time_hi_and_version, - gp->gp_type.clock_seq_hi_and_reserved, - gp->gp_type.clock_seq_low, - gp->gp_type.node[0], - gp->gp_type.node[1], - gp->gp_type.node[2], - gp->gp_type.node[3], - gp->gp_type.node[4], - gp->gp_type.node[5], - stats); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***