增加ACPI驱动, 实现关机
This commit is contained in:
parent
a118bbec58
commit
099592cdc2
|
@ -52,7 +52,7 @@ ISR_NOERRCODE 31
|
||||||
|
|
||||||
; 通用中断处理程序
|
; 通用中断处理程序
|
||||||
isr_common_stub:
|
isr_common_stub:
|
||||||
pusha ; 存储所有寄存器
|
pusha
|
||||||
|
|
||||||
mov ax, ds
|
mov ax, ds
|
||||||
push eax ; 存储ds
|
push eax ; 存储ds
|
||||||
|
@ -62,17 +62,17 @@ isr_common_stub:
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
call isr_handler ; 调用C语言处理函数
|
call isr_handler ; call isr_headler(registers_t reg);
|
||||||
pop eax ; 恢复各段
|
pop eax ; 恢复
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
popa ; 弹出所有寄存器
|
popa
|
||||||
|
|
||||||
add esp, 8 ; 弹出错误码和中断ID
|
add esp, 8 ; 弹出错误码和中断ID
|
||||||
iret ; 从中断返回
|
iret
|
||||||
|
|
||||||
%macro IRQ 2
|
%macro IRQ 2
|
||||||
global irq%1
|
global irq%1
|
||||||
|
|
|
@ -9,6 +9,7 @@ global tss_flush, gdt_flush, switch_to
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|
||||||
|
|
||||||
switch_to:
|
switch_to:
|
||||||
mov eax, [esp+4]
|
mov eax, [esp+4]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,278 @@
|
||||||
|
#include "../include/acpi.h"
|
||||||
|
#include "../include/memory.h"
|
||||||
|
#include "../include/graphics.h"
|
||||||
|
#include "../include/io.h"
|
||||||
|
#include "../include/isr.h"
|
||||||
|
#include "../include/timer.h"
|
||||||
|
|
||||||
|
uint16_t SLP_TYPa;
|
||||||
|
uint16_t SLP_TYPb;
|
||||||
|
uint32_t SMI_CMD;
|
||||||
|
uint8_t ACPI_ENABLE;
|
||||||
|
uint8_t ACPI_DISABLE;
|
||||||
|
uint32_t *PM1a_CNT;
|
||||||
|
uint32_t *PM1b_CNT;
|
||||||
|
uint8_t PM1_CNT_LEN;
|
||||||
|
uint16_t SLP_EN;
|
||||||
|
uint16_t SCI_EN;
|
||||||
|
|
||||||
|
acpi_rsdt_t *rsdt; // root system descript table
|
||||||
|
acpi_facp_t *facp; // fixed ACPI table
|
||||||
|
|
||||||
|
int acpi_enable() {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// check if enable ACPI
|
||||||
|
if (io_in16((uint32_t) PM1a_CNT) & SCI_EN) {
|
||||||
|
printf("ACPI already enable!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SMI_CMD && ACPI_ENABLE) {
|
||||||
|
// send ACPI_ENABLE cmd
|
||||||
|
io_out8((uint16_t)
|
||||||
|
SMI_CMD, ACPI_ENABLE);
|
||||||
|
|
||||||
|
// wait enable
|
||||||
|
for (i = 0; i < 300; i++) {
|
||||||
|
if (io_in16((uint32_t) PM1a_CNT) & SCI_EN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
clock_sleep(5);
|
||||||
|
}
|
||||||
|
// wait enable
|
||||||
|
if (PM1b_CNT) {
|
||||||
|
for (i = 0; i < 300; i++) {
|
||||||
|
if (io_in16((uint32_t) PM1b_CNT) & SCI_EN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
clock_sleep(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check enable status
|
||||||
|
if (i < 300) {
|
||||||
|
printf("[acpi]: Enable ACPI\n");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
printf("Counld't enable ACPI\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int acpi_disable() {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!io_in16((uint16_t)PM1a_CNT) &SCI_EN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (SMI_CMD || ACPI_DISABLE) {
|
||||||
|
io_out8((uint16_t)
|
||||||
|
SMI_CMD, ACPI_DISABLE);
|
||||||
|
|
||||||
|
for (i = 0; i < 300; i++) {
|
||||||
|
if (!io_in16((uint16_t)PM1a_CNT) &SCI_EN)
|
||||||
|
break;
|
||||||
|
clock_sleep(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 300; i++) {
|
||||||
|
if (!io_in16((uint16_t)PM1b_CNT) &SCI_EN)
|
||||||
|
break;
|
||||||
|
clock_sleep(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < 300) {
|
||||||
|
printf("ACPI Disable!\n");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
printf("Could't disable ACPI\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *AcpiGetRSDPtr() {
|
||||||
|
uint32_t *addr;
|
||||||
|
uint32_t *rsdt;
|
||||||
|
uint32_t ebda;
|
||||||
|
|
||||||
|
for (addr = (uint32_t *) 0x000E0000; addr < (uint32_t *) 0x00100000; addr += 0x10 / sizeof(addr)) {
|
||||||
|
rsdt = AcpiCheckRSDPtr(addr);
|
||||||
|
if (rsdt) {
|
||||||
|
return rsdt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// search extented bios data area for the root system description pointer signature
|
||||||
|
ebda = *(uint16_t * )
|
||||||
|
0x40E;
|
||||||
|
ebda = ebda * 0x10 & 0xfffff;
|
||||||
|
for (addr = (uint32_t *) ebda; addr < (uint32_t * )(ebda + 1024); addr += 0x10 / sizeof(addr)) {
|
||||||
|
rsdt = AcpiCheckRSDPtr(addr);
|
||||||
|
if (rsdt) {
|
||||||
|
return rsdt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_reset() {
|
||||||
|
uint8_t val;
|
||||||
|
if (!SCI_EN)
|
||||||
|
return;
|
||||||
|
while (1) {
|
||||||
|
// write ICH port
|
||||||
|
io_out8(0x92, 0x01);
|
||||||
|
// send RESET_VAL
|
||||||
|
io_out8((uint32_t) facp->RESET_REG.address, facp->RESET_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_off() {
|
||||||
|
if (!SCI_EN)
|
||||||
|
return;
|
||||||
|
while (1) {
|
||||||
|
printf("[acpi] send power off command!\n");
|
||||||
|
io_out16((uint32_t) PM1a_CNT, SLP_TYPa | SLP_EN);
|
||||||
|
if (!PM1b_CNT) {
|
||||||
|
io_out16((uint32_t) PM1b_CNT, SLP_TYPb | SLP_EN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int AcpiCheckHeader(void *ptr, uint8_t *sign) {
|
||||||
|
uint8_t * bptr = ptr;
|
||||||
|
uint32_t len = *(bptr + 4);
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
|
||||||
|
if (!memcmp(bptr, sign, 4)) {
|
||||||
|
while (len-- > 0) {
|
||||||
|
checksum += *bptr++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *AcpiCheckRSDPtr(void *ptr) {
|
||||||
|
char *sign = "RSD PTR ";
|
||||||
|
acpi_rsdptr_t *rsdp = ptr;
|
||||||
|
uint8_t * bptr = ptr;
|
||||||
|
uint32_t i = 0;
|
||||||
|
uint8_t check = 0;
|
||||||
|
|
||||||
|
// check signature
|
||||||
|
if (!memcmp(sign, bptr, 8)) {
|
||||||
|
printf("[acpi] rsdp found at %0x\n", bptr);
|
||||||
|
for (i = 0; i < sizeof(acpi_rsdptr_t); i++) {
|
||||||
|
check += *bptr;
|
||||||
|
bptr++;
|
||||||
|
}
|
||||||
|
if (!check) {
|
||||||
|
return (uint8_t * )
|
||||||
|
rsdp->rsdt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t AcpiGetMadtBase() {
|
||||||
|
uint32_t entrys = rsdt->length - HEADER_SIZE / 4;
|
||||||
|
uint32_t **p = &(rsdt->entry);
|
||||||
|
acpi_madt_t *madt = NULL;
|
||||||
|
|
||||||
|
while (--entrys) {
|
||||||
|
if (!AcpiCheckHeader(*p, "APIC")) {
|
||||||
|
madt = (acpi_madt_t *) *p;
|
||||||
|
return madt;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int AcpiSysInit() {
|
||||||
|
|
||||||
|
uint32_t **p;
|
||||||
|
uint32_t entrys;
|
||||||
|
uint32_t dsdtlen;
|
||||||
|
|
||||||
|
rsdt = (acpi_rsdt_t *) AcpiGetRSDPtr();
|
||||||
|
if (!rsdt || AcpiCheckHeader(rsdt, "RSDT") < 0) {
|
||||||
|
printf("No ACPI\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
entrys = rsdt->length - HEADER_SIZE / 4;
|
||||||
|
p = &(rsdt->entry);
|
||||||
|
while (entrys--) {
|
||||||
|
if (!AcpiCheckHeader(*p, "FACP")) {
|
||||||
|
facp = (acpi_facp_t *) *p;
|
||||||
|
|
||||||
|
ACPI_ENABLE = facp->ACPI_ENABLE;
|
||||||
|
ACPI_DISABLE = facp->ACPI_DISABLE;
|
||||||
|
|
||||||
|
SMI_CMD = facp->SMI_CMD;
|
||||||
|
|
||||||
|
PM1a_CNT = facp->PM1a_CNT_BLK;
|
||||||
|
PM1b_CNT = facp->PM1b_CNT_BLK;
|
||||||
|
|
||||||
|
PM1_CNT_LEN = facp->PM1_CNT_LEN;
|
||||||
|
|
||||||
|
SLP_EN = 1 << 13;
|
||||||
|
SCI_EN = 1;
|
||||||
|
|
||||||
|
uint8_t * S5Addr;
|
||||||
|
uint32_t dsdtlen;
|
||||||
|
|
||||||
|
if (!AcpiCheckHeader(facp->DSDT, "DSDT")) {
|
||||||
|
S5Addr = &(facp->DSDT->definition_block);
|
||||||
|
dsdtlen = facp->DSDT->length - HEADER_SIZE;
|
||||||
|
while (dsdtlen--) {
|
||||||
|
if (!memcmp(S5Addr, "_S5_", 4)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
S5Addr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dsdtlen) {
|
||||||
|
// check valid \_S5
|
||||||
|
if (*(S5Addr - 1) == 0x08 || (*(S5Addr - 2) == 0x08 && *(S5Addr - 1) == '\\')) {
|
||||||
|
S5Addr += 5;
|
||||||
|
S5Addr += ((*S5Addr & 0xC0) >> 6) + 2;
|
||||||
|
|
||||||
|
if (*S5Addr == 0x0A) {
|
||||||
|
S5Addr++;
|
||||||
|
}
|
||||||
|
SLP_TYPa = *(S5Addr) << 10;
|
||||||
|
S5Addr++;
|
||||||
|
if (*S5Addr == 0x0A) {
|
||||||
|
S5Addr++;
|
||||||
|
}
|
||||||
|
SLP_TYPb = *(S5Addr) << 10;
|
||||||
|
S5Addr++;
|
||||||
|
} else {
|
||||||
|
printf("[acpi] \\_S5 parse error!\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("[acpi] \\_S5 not present!\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("[acpi] no found DSDT table\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
printf("[acpi] No valid FACP present\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpi_install() {
|
||||||
|
AcpiSysInit();
|
||||||
|
acpi_enable();
|
||||||
|
// power init
|
||||||
|
// AcpiPowerInit();
|
||||||
|
}
|
|
@ -0,0 +1,218 @@
|
||||||
|
#ifndef CRASHPOWEROS_ACPI_H
|
||||||
|
#define CRASHPOWEROS_ACPI_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define HEADER_SIZE 36
|
||||||
|
|
||||||
|
#define ACPI_TABLE_RSDT ((void *)rsdt)
|
||||||
|
#define ACPI_TABLE_FACP ((void *)facp)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t addressid;
|
||||||
|
uint8_t register_bitwidth;
|
||||||
|
uint8_t register_bitoffset;
|
||||||
|
uint8_t access_size;
|
||||||
|
uint64_t address;
|
||||||
|
} acpi_address_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t signature[8];
|
||||||
|
uint8_t checksum;
|
||||||
|
uint8_t oem_id[6];
|
||||||
|
uint8_t revision;
|
||||||
|
uint32_t rsdt;
|
||||||
|
} acpi_rsdptr_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t signature[4]; // signature "RSDT"
|
||||||
|
uint32_t length;
|
||||||
|
uint8_t revision;
|
||||||
|
uint8_t checksum;
|
||||||
|
uint8_t oem_id[6];
|
||||||
|
uint8_t oem_tableid[8];
|
||||||
|
uint32_t oem_revision;
|
||||||
|
uint32_t creator_id;
|
||||||
|
uint32_t creator_revision;
|
||||||
|
uint32_t *entry;
|
||||||
|
} acpi_rsdt_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t signature[4];
|
||||||
|
uint32_t length;
|
||||||
|
uint8_t revision;
|
||||||
|
uint8_t checksum;
|
||||||
|
uint8_t oem_id[6];
|
||||||
|
uint8_t oem_tableid[8];
|
||||||
|
uint32_t oem_revision;
|
||||||
|
uint32_t creator_id;
|
||||||
|
uint8_t definition_block;
|
||||||
|
} acpi_dsdt_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t signature[4];
|
||||||
|
uint32_t length;
|
||||||
|
uint8_t FADT_major_version;
|
||||||
|
uint8_t checksum;
|
||||||
|
uint8_t ome_id[6];
|
||||||
|
uint8_t oem_tableid[8];
|
||||||
|
uint32_t oem_revision;
|
||||||
|
uint32_t creator_id;
|
||||||
|
uint32_t creator_revision;
|
||||||
|
|
||||||
|
uint32_t FIRMWARE_CTRL;
|
||||||
|
acpi_dsdt_t *DSDT;
|
||||||
|
|
||||||
|
// no longer in use
|
||||||
|
uint8_t unused0;
|
||||||
|
|
||||||
|
uint8_t PM_profile;
|
||||||
|
uint16_t SCI_INT;
|
||||||
|
uint32_t SMI_CMD;
|
||||||
|
uint8_t ACPI_ENABLE;
|
||||||
|
uint8_t ACPI_DISABLE;
|
||||||
|
uint8_t S4BIOS_REQ;
|
||||||
|
uint8_t PSTATE_CNT;
|
||||||
|
uint32_t PM1a_EVT_BLK;
|
||||||
|
uint32_t PM1b_EVT_BLK;
|
||||||
|
uint32_t PM1a_CNT_BLK;
|
||||||
|
uint32_t PM1b_CNT_BLK;
|
||||||
|
uint32_t PM2_CNT_BLK;
|
||||||
|
uint32_t PM_TMR_BLK;
|
||||||
|
uint32_t GPE0_BLK;
|
||||||
|
uint32_t GPE1_BLK;
|
||||||
|
uint8_t PM1_EVT_LEN;
|
||||||
|
uint8_t PM1_CNT_LEN;
|
||||||
|
uint8_t PM2_CNT_LEN;
|
||||||
|
uint8_t PM_TMR_LEN;
|
||||||
|
uint8_t GPE0_BLK_LEN;
|
||||||
|
uint8_t GPE1_BLK_LEN;
|
||||||
|
uint8_t GPE1_BASE;
|
||||||
|
uint8_t CST_CNT;
|
||||||
|
uint16_t P_LVL2_LAT;
|
||||||
|
uint16_t P_LVL3_LAT;
|
||||||
|
uint16_t FLUSH_SIZE;
|
||||||
|
uint16_t FLUSH_STRIDE;
|
||||||
|
uint8_t DUTY_OFFSET;
|
||||||
|
uint8_t DUTY_WIDTH;
|
||||||
|
uint8_t DAY_ALRM;
|
||||||
|
uint8_t MON_ALRM;
|
||||||
|
uint8_t CENTURY;
|
||||||
|
|
||||||
|
// reserved in ACPI 1.0,used in since ACPI 2.0+
|
||||||
|
uint16_t IAPC_BOOT_ARCH;
|
||||||
|
uint8_t unused1;
|
||||||
|
uint32_t flags;
|
||||||
|
|
||||||
|
acpi_address_t RESET_REG;
|
||||||
|
uint8_t RESET_VALUE;
|
||||||
|
uint16_t ARM_BOOT_ARCH;
|
||||||
|
uint8_t FADT_minjor_version;
|
||||||
|
|
||||||
|
// there used in 64bits address mode
|
||||||
|
uint64_t *X_FIREWARE_CTRL;
|
||||||
|
uint64_t *X_DSDT;
|
||||||
|
acpi_address_t X_PM1a_EVT_BLK;
|
||||||
|
acpi_address_t X_PM1b_EVT_BLK;
|
||||||
|
acpi_address_t X_PM1a_CNT_BLK;
|
||||||
|
acpi_address_t X_PM1b_CNT_BLK;
|
||||||
|
acpi_address_t X_PM2_CNT_BLK;
|
||||||
|
acpi_address_t X_PM_TMR_BLK;
|
||||||
|
acpi_address_t X_GPE0_BLK;
|
||||||
|
acpi_address_t X_GPE1_BLK;
|
||||||
|
acpi_address_t SLEEP_CONTROL_REG;
|
||||||
|
acpi_address_t SLEEP_STATUS_REG;
|
||||||
|
uint8_t hypervisor_vendor_id;
|
||||||
|
} acpi_facp_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t sign[4]; // string 'APIC'
|
||||||
|
uint32_t len;
|
||||||
|
uint8_t revision;
|
||||||
|
uint8_t chksum;
|
||||||
|
uint8_t oemid[6];
|
||||||
|
uint8_t oemtableid[8];
|
||||||
|
uint8_t oemrevision[4];
|
||||||
|
uint8_t create_id[4];
|
||||||
|
uint8_t create_revision[4];
|
||||||
|
uint32_t local_apic; // local apic address
|
||||||
|
uint32_t flags; // flags =1 install DUAL PIC hardware
|
||||||
|
} acpi_madt_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t ioapic_id;
|
||||||
|
uint8_t reserved;
|
||||||
|
uint32_t ioapic_base; // iobase base
|
||||||
|
uint32_t gsi_base;
|
||||||
|
} madt_ioapic_entry_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t bus;
|
||||||
|
uint8_t irq;
|
||||||
|
uint32_t gsi;
|
||||||
|
uint16_t flags;
|
||||||
|
} madt_ioapic_int_assert_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t nmi;
|
||||||
|
uint8_t reserved;
|
||||||
|
uint16_t flags;
|
||||||
|
uint32_t gsi;
|
||||||
|
} madt_ioapic_nmi_assert_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MADT_PROCESSOR_LOCAL_APIC = 0,
|
||||||
|
MADT_PRCESSOR_IOAPIC = 1,
|
||||||
|
MADT_LOCAL_INT_ASSERT = 2,
|
||||||
|
MADT_LOCAL_NMI_ASSERT = 3,
|
||||||
|
} madt_entry_t;
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t ACPI_processorID;
|
||||||
|
uint8_t APIC_ID;
|
||||||
|
uint32_t flags; // bit0 = processor enabled bit1 = online capable
|
||||||
|
} madt_processor_localAPIC_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
uint8_t *AcpiGetRSDPtr();
|
||||||
|
int AcpiCheckHeader(void *ptr, uint8_t *sign);
|
||||||
|
uint8_t *AcpiCheckRSDPtr(void *ptr);
|
||||||
|
uint32_t AcpiGetMadtBase();
|
||||||
|
void power_off();
|
||||||
|
void power_reset();
|
||||||
|
int acpi_enable();
|
||||||
|
int acpi_disable();
|
||||||
|
void acpi_install();
|
||||||
|
|
||||||
|
#endif //CRASHPOWEROS_ACPI_H
|
|
@ -18,5 +18,6 @@ void cmd_mkdir(int argc, char **argv);
|
||||||
void cmd_read(int argc, char **argv);
|
void cmd_read(int argc, char **argv);
|
||||||
void cmd_cat(int argc, char **argv);
|
void cmd_cat(int argc, char **argv);
|
||||||
void cmd_ls();
|
void cmd_ls();
|
||||||
|
void cmd_shutdown();
|
||||||
|
|
||||||
#endif //CRASHPOWEROS_SHELL_H
|
#endif //CRASHPOWEROS_SHELL_H
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct task_struct {
|
||||||
char *name; // 进程名
|
char *name; // 进程名
|
||||||
void *stack; // 进程的内核栈地址
|
void *stack; // 进程的内核栈地址
|
||||||
page_directory_t *pgd_dir; // 进程页表
|
page_directory_t *pgd_dir; // 进程页表
|
||||||
struct context context; // 进程切换需要的上下文信息
|
struct context context; // 上下文信息
|
||||||
struct task_struct *next; // 链表指针
|
struct task_struct *next; // 链表指针
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,4 +46,6 @@ void change_task_to(struct task_struct *next);
|
||||||
|
|
||||||
void task_kill(int pid);
|
void task_kill(int pid);
|
||||||
|
|
||||||
|
void kill_all_task();
|
||||||
|
|
||||||
#endif //CRASHPOWEROS_TASK_H
|
#endif //CRASHPOWEROS_TASK_H
|
||||||
|
|
|
@ -10,19 +10,24 @@
|
||||||
#include "../include/keyboard.h"
|
#include "../include/keyboard.h"
|
||||||
#include "../include/shell.h"
|
#include "../include/shell.h"
|
||||||
#include "../include/date.h"
|
#include "../include/date.h"
|
||||||
|
#include "../include/acpi.h"
|
||||||
|
|
||||||
extern uint32_t end;
|
extern uint32_t end;
|
||||||
extern int status;
|
extern int status;
|
||||||
uint32_t placement_address = (uint32_t) & end;
|
uint32_t placement_address = (uint32_t) & end;
|
||||||
|
|
||||||
void reset_kernel(){
|
void reset_kernel(){
|
||||||
printf("Restart %s for x86...",OS_NAME);
|
printf("Restart %s for x86...\n",OS_NAME);
|
||||||
|
kill_all_task();
|
||||||
clock_sleep(10);
|
clock_sleep(10);
|
||||||
outb(0x64,0xfe);
|
power_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown_kernel(){
|
void shutdown_kernel(){
|
||||||
//TODO ACPI Driver
|
printf("Shutdown %s for x86...\n",OS_NAME);
|
||||||
|
kill_all_task();
|
||||||
|
clock_sleep(10);
|
||||||
|
power_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernel_main(multiboot_t *multiboot) {
|
void kernel_main(multiboot_t *multiboot) {
|
||||||
|
@ -40,10 +45,12 @@ void kernel_main(multiboot_t *multiboot) {
|
||||||
idt_install();
|
idt_install();
|
||||||
printf("[\035kernel\036]: description table config success!\n");
|
printf("[\035kernel\036]: description table config success!\n");
|
||||||
init_timer(10);
|
init_timer(10);
|
||||||
|
acpi_install();
|
||||||
|
printf("[\035kernel\036]: ACPI enable success!\n");
|
||||||
init_page();
|
init_page();
|
||||||
printf("[\035kernel\036]: page set success!\n");
|
printf("[\035kernel\036]: page set success!\n");
|
||||||
init_sched();
|
init_sched();
|
||||||
printf("[\035kernel\036]: PCB load success!\n");
|
printf("[\035kernel\036]: task load success!\n");
|
||||||
init_keyboard();
|
init_keyboard();
|
||||||
printf("[\035kernel\036]: Keyboard driver load success!\n");
|
printf("[\035kernel\036]: Keyboard driver load success!\n");
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "../include/task.h"
|
#include "../include/task.h"
|
||||||
#include "../include/common.h"
|
#include "../include/common.h"
|
||||||
#include "../include/graphics.h"
|
#include "../include/graphics.h"
|
||||||
|
#include "../include/io.h"
|
||||||
|
|
||||||
struct task_struct *running_proc_head = NULL;
|
struct task_struct *running_proc_head = NULL;
|
||||||
struct task_struct *wait_proc_head = NULL;
|
struct task_struct *wait_proc_head = NULL;
|
||||||
|
@ -111,7 +112,8 @@ void task_kill(int pid){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("Task [%s] exit code: -130.\n",argv->name);
|
printf("Task [%s] exit code: -130.\n",argv->name);
|
||||||
|
io_sti();
|
||||||
|
kfree(argv);
|
||||||
struct task_struct *head = running_proc_head;
|
struct task_struct *head = running_proc_head;
|
||||||
struct task_struct *last = NULL;
|
struct task_struct *last = NULL;
|
||||||
while (1){
|
while (1){
|
||||||
|
@ -122,6 +124,7 @@ void task_kill(int pid){
|
||||||
last = head;
|
last = head;
|
||||||
head = head->next;
|
head = head->next;
|
||||||
}
|
}
|
||||||
|
io_cli();
|
||||||
}
|
}
|
||||||
|
|
||||||
void schedule() {
|
void schedule() {
|
||||||
|
@ -137,6 +140,7 @@ void change_task_to(struct task_struct *next) {
|
||||||
|
|
||||||
//switch_page_directory(current->pgd_dir);
|
//switch_page_directory(current->pgd_dir);
|
||||||
switch_to(&(prev->context), &(current->context));
|
switch_to(&(prev->context), &(current->context));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +189,18 @@ void kthread_exit() {
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kill_all_task(){
|
||||||
|
struct task_struct *head = running_proc_head;
|
||||||
|
while (1){
|
||||||
|
head = head->next;
|
||||||
|
if(head == NULL || head->pid == running_proc_head->pid){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(head->pid == current->pid) continue;
|
||||||
|
task_kill(head->pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void init_sched() {
|
void init_sched() {
|
||||||
// 为当前执行流创建信息结构体 该结构位于当前执行流的栈最低端
|
// 为当前执行流创建信息结构体 该结构位于当前执行流的栈最低端
|
||||||
current = (struct task_struct *) kmalloc(sizeof(struct task_struct));
|
current = (struct task_struct *) kmalloc(sizeof(struct task_struct));
|
||||||
|
|
|
@ -184,6 +184,10 @@ void cmd_reset(){
|
||||||
reset_kernel();
|
reset_kernel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmd_shutdown(){
|
||||||
|
shutdown_kernel();
|
||||||
|
}
|
||||||
|
|
||||||
void setup_shell(){
|
void setup_shell(){
|
||||||
vga_clear();
|
vga_clear();
|
||||||
printf("%s for x86 [Version %s] \n",OS_NAME, OS_VERSION);
|
printf("%s for x86 [Version %s] \n",OS_NAME, OS_VERSION);
|
||||||
|
@ -225,6 +229,8 @@ void setup_shell(){
|
||||||
cmd_del(argc, argv);
|
cmd_del(argc, argv);
|
||||||
else if (!strcmp("reset", argv[0]))
|
else if (!strcmp("reset", argv[0]))
|
||||||
cmd_reset();
|
cmd_reset();
|
||||||
|
else if (!strcmp("shutdown", argv[0])||!strcmp("exit", argv[0]))
|
||||||
|
cmd_shutdown();
|
||||||
else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) {
|
else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) {
|
||||||
vga_writestring("-=[\037CrashPowerShell Helper\036]=-\n");
|
vga_writestring("-=[\037CrashPowerShell Helper\036]=-\n");
|
||||||
vga_writestring("help ? h \032Print shell help info.\036\n");
|
vga_writestring("help ? h \032Print shell help info.\036\n");
|
||||||
|
@ -238,6 +244,7 @@ void setup_shell(){
|
||||||
vga_writestring("sysinfo \032Print system info.\036\n");
|
vga_writestring("sysinfo \032Print system info.\036\n");
|
||||||
vga_writestring("proc [kill<pid>|list] \032Lists all running processes.\036\n");
|
vga_writestring("proc [kill<pid>|list] \032Lists all running processes.\036\n");
|
||||||
vga_writestring("reset \032Reset OS.\036\n");
|
vga_writestring("reset \032Reset OS.\036\n");
|
||||||
|
vga_writestring("shutdown exit \032Shutdown OS.\036\n");
|
||||||
} else printf("\033[Shell]: Unknown command '%s'.\036\n", argv[0]);
|
} else printf("\033[Shell]: Unknown command '%s'.\036\n", argv[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue