Annotation of kernel/machdep/i386/APM_i386.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /*
        !            26:  * Copyright 1994 NeXT Computer, Inc.
        !            27:  * All rights reserved.
        !            28:  */
        !            29: 
        !            30: /*
        !            31:  * Power Management (PM) kernel interface.
        !            32:  * This implementation uses the Microsoft/Intel APM 1.1 interface.
        !            33:  */
        !            34: 
        !            35: #import <bsd/sys/time.h>
        !            36: 
        !            37: #import <kern/power.h>
        !            38: 
        !            39: #import <mach/mach_types.h>
        !            40: 
        !            41: #import <machdep/i386/pmap.h>
        !            42: #import <machdep/i386/seg.h>
        !            43: #import <machdep/i386/table_inline.h>
        !            44: #import <machdep/i386/desc_inline.h>
        !            45: #import <machdep/i386/kernBootStruct.h>
        !            46: #import <machdep/i386/bios.h>
        !            47: #import <machdep/i386/APM_BIOS.h>
        !            48: 
        !            49: static boolean_t APM_BIOS_connected;
        !            50: static struct {
        !            51:     unsigned major;
        !            52:     unsigned minor;
        !            53: } APM_BIOS_version;
        !            54: 
        !            55: #define VERSION_EQ(maj,min) ((APM_BIOS_version.major == (maj)) && \
        !            56:                          (APM_BIOS_version.minor == (min)))
        !            57: #define VERSION_GE(maj,min) ((APM_BIOS_version.major > (maj)) || \
        !            58:                            ((APM_BIOS_version.major == (maj)) && \
        !            59:                             (APM_BIOS_version.minor >= (min))))
        !            60: /*
        !            61:  * Note: we assume that the power management version is 1.0,
        !            62:  * because some machine report a bogus version.
        !            63:  * If we do the standard 1.0 "APM Connect" BIOS call in the booter,
        !            64:  * then the BIOS should give us APM 1.0 behavior.
        !            65:  */
        !            66: 
        !            67: static void
        !            68: setUpGdtEntries()
        !            69: {
        !            70:     KERNBOOTSTRUCT *kbp = KERNSTRUCT_ADDR;
        !            71:     
        !            72:     map_code((data_desc_t *) sel_to_gdt_entry(APMCODE32_SEL),
        !            73:             (vm_offset_t) KERNEL_LINEAR_BASE + kbp->apm_config.cs32_base,
        !            74:             (vm_size_t) kbp->apm_config.cs_length,
        !            75:             KERN_PRIV,
        !            76:             FALSE
        !            77:            );
        !            78: 
        !            79:     map_code_16((data_desc_t *) sel_to_gdt_entry(APMCODE16_SEL),
        !            80:             (vm_offset_t) KERNEL_LINEAR_BASE + kbp->apm_config.cs16_base,
        !            81:             (vm_size_t) kbp->apm_config.cs_length,
        !            82:             KERN_PRIV,
        !            83:             FALSE
        !            84:            );
        !            85: 
        !            86:     map_data((data_desc_t *) sel_to_gdt_entry(APMDATA_SEL),
        !            87:             (vm_offset_t) KERNEL_LINEAR_BASE + kbp->apm_config.ds_base,
        !            88:             (vm_size_t) kbp->apm_config.ds_length,
        !            89:             KERN_PRIV,
        !            90:             FALSE
        !            91:            );
        !            92:            
        !            93:     APM_BIOS_addr = kbp->apm_config.entry_offset;
        !            94: }
        !            95: 
        !            96: /*
        !            97:  * Initialize PM support.  Returns TRUE if PM is available.
        !            98:  */
        !            99: PMReturn PMConnect(void)
        !           100: {
        !           101:     KERNBOOTSTRUCT *kbp = KERNSTRUCT_ADDR;
        !           102: 
        !           103:     APM_BIOS_version.major = kbp->apm_config.major_vers;
        !           104:     APM_BIOS_version.minor = kbp->apm_config.minor_vers;
        !           105:     
        !           106:     if (kbp->apm_config.connected) {
        !           107:        APM_BIOS_connected = TRUE;
        !           108:        setUpGdtEntries();
        !           109:        printf("Power management is enabled.\n");
        !           110:        return PM_R_SUCCESS;
        !           111:     }
        !           112:     return PM_R_NO_PM;
        !           113: }
        !           114: 
        !           115: /*
        !           116:  * Return PM control to previous user (probably the BIOS).
        !           117:  */
        !           118: PMReturn PMDisconnect(void)
        !           119: {
        !           120:     return PM_R_SUCCESS;
        !           121: }
        !           122: 
        !           123: /*
        !           124:  * Inform PM of the CPU state.  If the CPU is idle, PM may
        !           125:  * put the CPU in a power-saving state until the next system event
        !           126:  * (typically an interrupt).  Marking the CPU busy will ensure
        !           127:  * that the CPU is running at full speed.
        !           128:  */
        !           129: PMReturn PMSetCpuState(
        !           130:     PMCpuState state
        !           131: )
        !           132: {
        !           133:     boolean_t ret;
        !           134:     
        !           135:     if (APM_BIOS_connected) {
        !           136:        switch (state) {
        !           137:        case PM_CPU_IDLE:
        !           138:            ret = APMBIOS_Idle();
        !           139:            break;
        !           140:        case PM_CPU_BUSY:
        !           141:            ret = APMBIOS_Busy();
        !           142:            break;
        !           143:        default:
        !           144:            ret = FALSE;
        !           145:        }
        !           146:        if (ret == FALSE)
        !           147:            return PM_R_BAD_STATE;
        !           148:     } else {
        !           149:        if (state == PM_CPU_IDLE) {
        !           150:            asm volatile("hlt");
        !           151:        }
        !           152:     }
        !           153:     return PM_R_SUCCESS;
        !           154: }
        !           155: 
        !           156: /*
        !           157:  * Set the power state of a device or the entire computer.
        !           158:  */
        !           159: PMReturn PMSetPowerState(
        !           160:     PMDeviceID device,
        !           161:     PMPowerState state
        !           162: )
        !           163: {
        !           164:     union {
        !           165:        struct {
        !           166:            unsigned int        deviceNumber    :8;
        !           167:            unsigned int        deviceType      :8;
        !           168:        } device;
        !           169:        unsigned short data;
        !           170:     } du;
        !           171:     union {
        !           172:        PMPowerState state;
        !           173:        unsigned short data;
        !           174:     } su;
        !           175:     PMReturn ret;
        !           176:     
        !           177:     /* Eventually this should differentiate between devices. */
        !           178:     if (device.deviceType == PM_SYSTEM && device.deviceNumber == 1) {
        !           179:            _io_setDriverPowerState(state);
        !           180:     }
        !           181: 
        !           182:     if (APM_BIOS_connected) {
        !           183:        if (device.deviceType == PM_SYSTEM && device.deviceNumber == 1) {
        !           184:            /*
        !           185:             * In PM 1.1 and 1.0,
        !           186:             * you can't set the system state to "ready".
        !           187:             */
        !           188:            if (state == PM_READY)
        !           189:                return PM_R_BAD_STATE;
        !           190:            /*
        !           191:             * In PM 1.0, you can't set the system state to "off".
        !           192:             */
        !           193:            if (state == PM_OFF)
        !           194:                return PM_R_BAD_STATE;
        !           195:        }
        !           196:        du.device.deviceNumber = device.deviceNumber;
        !           197:        du.device.deviceType = device.deviceType;
        !           198:        su.state = state;
        !           199:        return APMBIOS_SetPowerState(du.data, su.data);
        !           200:     }
        !           201:     return PM_R_NOT_CONNECTED;
        !           202: }
        !           203: 
        !           204: /*
        !           205:  * Get a power event from PM, if one has occurred.
        !           206:  */
        !           207: PMReturn PMGetPowerEvent(
        !           208:     PMPowerEvent *event
        !           209: )
        !           210: {
        !           211:     unsigned short event_code;
        !           212:     PMReturn ret;
        !           213: 
        !           214:     if (APM_BIOS_connected) {
        !           215:        if ((ret = APMBIOS_GetPowerEvent(&event_code)) == PM_R_SUCCESS) {
        !           216:            *event = (PMPowerEvent)event_code;
        !           217:            return PM_R_SUCCESS;
        !           218:        }
        !           219:        return ret;
        !           220:     }
        !           221:     return PM_R_NOT_CONNECTED;
        !           222: }
        !           223: 
        !           224: /*
        !           225:  * Get the power state of the computer.
        !           226:  */
        !           227: PMReturn PMGetPowerStatus(
        !           228:     PMPowerStatus *status
        !           229: )
        !           230: {
        !           231:     unsigned char line_status, batt_status, batt_life;
        !           232:     PMReturn ret;
        !           233:     
        !           234:     if (APM_BIOS_connected) {
        !           235:        if ((ret = APMBIOS_GetPowerStatus(&line_status, &batt_status, 
        !           236:                                          &batt_life)) == PM_R_SUCCESS) {
        !           237:            status->lineStatus = (PMLineStatus)line_status;
        !           238:            status->batteryStatus = (PMBatteryStatus)batt_status;
        !           239:            status->batteryLife = (batt_life == 0xFF) ? -1 : (int)batt_life;
        !           240:            return PM_R_SUCCESS;
        !           241:        } else {
        !           242:            return ret;
        !           243:        }
        !           244:     }
        !           245:     return PM_R_NOT_CONNECTED;
        !           246: }
        !           247: 
        !           248: /*
        !           249:  * Enable or disable power management by the computer.
        !           250:  * If enable == PM_ENABLED, the computer can take power saving steps
        !           251:  * when the CPU state is idle.  If enable == PM_DISABLED, no automatic
        !           252:  * power saving steps will be taken and power management functions
        !           253:  * will be disabled.
        !           254:  */
        !           255: PMReturn PMSetPowerManagement(
        !           256:     PMDeviceID device,
        !           257:     PMPowerManagementState state
        !           258: )
        !           259: {
        !           260:     if (APM_BIOS_connected) {
        !           261:        if (device.deviceType == PM_SYSTEM && device.deviceNumber == 1)
        !           262:            return APMBIOS_SetSystemPowerManagement(state);
        !           263:        else
        !           264:            return PM_R_BAD_ID;
        !           265:     }
        !           266: 
        !           267:     return PM_R_NOT_CONNECTED;
        !           268: }
        !           269: 
        !           270: /*
        !           271:  * Restores the default settings for all power management settings.
        !           272:  */
        !           273: PMReturn PMRestoreDefaults(void)
        !           274: {
        !           275:     if (APM_BIOS_connected)
        !           276:        return APMBIOS_RestoreDefaults();
        !           277:     else
        !           278:        return PM_R_NOT_CONNECTED;
        !           279: }
        !           280: 
        !           281: /*
        !           282:  * Update current kernel clock from real-time clock.
        !           283:  */
        !           284: void PMUpdateClock(void)
        !           285: {
        !           286: /* THIS IS WRONG!!
        !           287:     extern struct timeval      time;
        !           288:     readtodc(&time.tv_sec);
        !           289: */
        !           290: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.