Package org.jnode.vm.x86

Source Code of org.jnode.vm.x86.MPFloatingPointerStructure

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.vm.x86;

import org.jnode.system.resource.MemoryResource;
import org.jnode.system.resource.MemoryScanner;
import org.jnode.system.resource.ResourceManager;
import org.jnode.system.resource.ResourceNotFreeException;
import org.jnode.system.resource.ResourceOwner;
import org.jnode.util.NumberUtils;
import org.jnode.annotation.MagicPermission;
import org.jnode.bootlog.BootLogInstance;
import org.vmmagic.unboxed.Address;

/**
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
@MagicPermission
final class MPFloatingPointerStructure {

    private MemoryResource mem;

    private static final int MAGIC = 0x5F504D5F; // _MP_

    private MPConfigTable configTable;

    /**
     * Find the MP floating pointer structure.
     *
     * @return The found structure, or null if not found.
     */
    public static MPFloatingPointerStructure find(ResourceManager rm,
                                                  ResourceOwner owner) {
        MPFloatingPointerStructure mp;
        mp = find(rm, owner, 639 * 1024, 640 * 1024);
        if (mp == null) {
            mp = find(rm, owner, 0xF0000, 0xFFFFF);
        }
        if (mp == null) {
            return null;
        }
        return mp;
    }

    /**
     * Release the resources hold by this structure.
     */
    public void release() {
        mem.release();
    }

    /**
     * Gets the length of this structure in bytes.
     *
     * @return the length
     */
    final int getLength() {
        return (16 * (mem.getByte(0x08) & 0xFF));
    }

    /**
     * Gets the specification revision level
     */
    final int getSpecRevision() {
        return mem.getByte(0x09);
    }

    /**
     * Gets the MP system configuration type. When non-zero, a default
     * configuration is present, when zero an MP configuration table must be
     * present.
     *
     * @return
     */
    final int getSystemConfigurationType() {
        return mem.getByte(0x0B);
    }

    /**
     * Is the IMCR register present. This flag can be used to determine whether
     * PIC Mode or Virtual Wire mode is implemented by the system.
     *
     * @return
     */
    final boolean isIMCRPresent() {
        return ((mem.getByte(0x0C) & 0x80) != 0);
    }

    /**
     * @see java.lang.Object#toString()
     */
    public String toString() {
        return "MP 1." + getSpecRevision() + ", config-type 0x"
            + NumberUtils.hex(getSystemConfigurationType(), 2) + ", IMCR "
            + (isIMCRPresent() ? "present" : "not present")
            + ", ConfigTableAt 0x" + NumberUtils.hex(mem.getInt(0x04));
    }

    /**
     * Gets the physical address of the MP configuration table.
     *
     * @return the address
     */
    final Address getMPConfigTablePtr() {
        return Address.fromIntZeroExtend(mem.getInt(0x04));
    }

    /**
     * Gets the MPConfig table.
     */
    final MPConfigTable getMPConfigTable() {
        return configTable;
    }

    /**
     * Initialize this instance.
     *
     * @param mem
     */
    private MPFloatingPointerStructure(MemoryResource mem) {
        this.mem = mem;
    }

    /**
     * Is this a valid MPFP structure?
     */
    private final boolean isValid() {
        // Length should be 16
        if (getLength() != 16) {
            return false;
        }
        // Check checksum
        int sum = 0;
        for (int i = 0; i < 16; i++) {
            sum += mem.getByte(i) & 0xFF;
            sum &= 0xFF;
        }
        if (sum != 0) {
            return false;
        }

        return true;
    }

    private final boolean initConfigTable(ResourceManager rm,
                                          ResourceOwner owner) {
        final Address tablePtr = getMPConfigTablePtr();
        int size = 0x2C; // Base table length
        try {
            MemoryResource mem = rm.claimMemoryResource(owner, tablePtr, size,
                ResourceManager.MEMMODE_NORMAL);
            // Read the table length
            int baseTableLen = mem.getChar(4);
            mem.release();
            // Claim the full table.
            // BootLogInstance.get().info("baseTableLength " + baseTableLen);
            size = baseTableLen;
            mem = rm.claimMemoryResource(owner, tablePtr, size,
                ResourceManager.MEMMODE_NORMAL);
            this.configTable = new MPConfigTable(mem);
            if (configTable.isValid()) {
                return true;
            } else {
                configTable.release();
                configTable = null;
                return false;
            }
        } catch (ResourceNotFreeException ex) {
            BootLogInstance.get().warn("Cannot claim MP config table region");
            ex.printStackTrace();
            return false;
        }
    }

    /**
     * Find the structure between to pointers.
     *
     * @param rm
     * @param owner
     * @param startPtr
     * @param endPtr
     * @return The structure found, or null if not found
     */
    private static MPFloatingPointerStructure find(ResourceManager rm,
                                                   ResourceOwner owner, int startPtr, int endPtr) {
        final MemoryScanner ms = rm.getMemoryScanner();
        Address ptr = Address.fromIntZeroExtend(startPtr);
        int size = endPtr - startPtr;
        final int stepSize = 16;
        while (size > 0) {
            Address res = ms.findInt32(ptr, size, MAGIC, stepSize);
            if (res != null) {
                try {
                    final MemoryResource mem;
                    mem = rm.claimMemoryResource(owner, ptr, 16,
                        ResourceManager.MEMMODE_NORMAL);
                    final MPFloatingPointerStructure mp = new MPFloatingPointerStructure(
                        mem);
                    if (mp.isValid()) {
                        if (mp.initConfigTable(rm, owner)) {
                            return mp;
                        }
                    }
                    mp.release();
                } catch (ResourceNotFreeException ex) {
                    BootLogInstance.get().warn("Cannot claim MP region");
                }
            }
            ptr = ptr.add(stepSize);
            size -= stepSize;
        }
        return null;
    }
}
TOP

Related Classes of org.jnode.vm.x86.MPFloatingPointerStructure

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.