1
					Lowlevel-Coding / Re: x86-Startup
« am: 23. December 2015, 17:15 »
					Danke fuer den Tipp. Hatte bisher nur mit QEmu getestet.
Jetzt klappt es und die anderen CPUs booten
				Jetzt klappt es und die anderen CPUs booten
04. November 2025, 01:14
Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.
static __inline int __MaskLVT(ApicRegister i_register) {
    UInt32 value;
    int retval = CPU_ApicRead(i_register, &value);
    if (ESuccess != retval)
        return retval;
    return CPU_ApicWrite(i_register, value | (1 << 16));
}
static __inline int __CleanLApic() {
    UInt32 maxLvt;
    int retval = CPU_ApicRead(LocalApicVersion, &maxLvt);
    if (ESuccess != retval)
        return retval;
    maxLvt = (maxLvt >> 16) & 0xff;
    if (3 <= maxLvt) {
        retval = CPU_ApicWrite(LvtError, 0xfe | (1 << 16));
        if (ESuccess != retval)
            return retval;
    }
    retval = __MaskLVT(LvtTimer);
    if (ESuccess != retval)
        return retval;
    retval = __MaskLVT(LvtLInt0);
    if (ESuccess != retval)
        return retval;
    retval = __MaskLVT(LvtLInt1);
    if (ESuccess != retval)
        return retval;
    if (4 <= maxLvt) {
        retval = __MaskLVT(LvtPerformanceMonitoringCounters);
        if (ESuccess != retval)
            return retval;
    }
    retval = CPU_ApicWrite(LvtTimer, 1 << 16);
    if (ESuccess != retval)
        return retval;
    retval = CPU_ApicWrite(LvtLInt0, 1 << 16);
    if (ESuccess != retval)
        return retval;
    retval = CPU_ApicWrite(LvtLInt1, 1 << 16);
    if (ESuccess != retval)
        return retval;
    if (3 <= maxLvt) {
        retval = CPU_ApicWrite(LvtError, 1 << 16);
        if (ESuccess != retval)
            return retval;
    }
    if (4 <= maxLvt) {
        retval = CPU_ApicWrite(LvtPerformanceMonitoringCounters, 1 << 16);
        if (ESuccess != retval)
            return retval;
    }
    return ESuccess;
}
static __inline int __InitializeLogicDestination() {
    UInt32 value;
    int retval = CPU_ApicWrite(DestinationFormat, 0xffffffff);
    if (ESuccess != retval)
        return retval;
    retval = CPU_ApicRead(LogicalDestination, &value);
    if (ESuccess != retval)
        return retval;
    value &= ~(0xff << 24);
    UInt32 cpuId;
    retval = CPU_GetProcessorId(&cpuId);
    if (ESuccess != retval)
        return retval;
    value |= ((1 << cpuId) << 24);
    return CPU_ApicWrite(LogicalDestination, value);
}
int CPU_ApicInitialize() {
    UInt32 value;
    /* disable the PIC */
    CPU_IOPortWriteByte(0xa1, 0xff);
    CPU_IOPortWriteByte(0x21, 0xff);
    int retval = __CleanLApic();
    if (ESuccess != retval)
        return retval;
    retval = __InitializeLogicDestination();
    if (ESuccess != retval)
        return retval;
    /* set the task priority */
    retval = CPU_ApicRead(TaskPriority, &value);
    if (ESuccess != retval)
        return retval;
    value &= ~0xff;
    retval = CPU_ApicWrite(TaskPriority, value);
    if (ESuccess != retval)
        return retval;
    /* all done - activate the lapic */
    retval = CPU_ApicRead(SpuriousInterruptVector, &value);
    if (ESuccess != retval)
        return retval;
    value &= ~0xff;
    value |= (1 << 8) | 0xff;
    retval = CPU_ApicWrite(SpuriousInterruptVector, value);
    if (ESuccess != retval)
        return retval;
    return ESuccess;
}
static __inline int __BootApplicationProcessor(UInt16 i_cpuCount, UInt32 i_stacks[]) {
    UIntPtr size = (UIntPtr)__trampoline_smp_end - (UIntPtr)__trampoline_smp_start;
    UInt32* stackPtr = (UInt32*)(0x7000 + size - 8);
    UInt8 acpis[i_cpuCount];
    UInt32 status;
    int retval = ACPI_GetProcessorInformation(acpis);
    if (ESuccess != retval) {
        KLog(Error, "Unable to get processor information: %d\n", retval);
        return retval;
    }
    UInt32 ownId;
    retval = CPU_GetProcessorId(&ownId);
    if (ESuccess != retval) {
        KLog(Error, "Unable to get the own CPU-ID: %d\n", retval);
        return retval;
    }
    UInt32 low, high;
    CPU_ReadMsr(0x1B, &low, &high);
    if (0 == (0x800 & low)) {
        KLog(Error, "LAPIC is not disabled\n");
        return -ENoPermission;
    }
    UInt32 value;
    retval = CPU_ApicRead(ErrorStatus, &value);
    for (UInt16 i = 0, c = 0; i < i_cpuCount; i++) {
        if (ownId == acpis[i])
            continue;
        *stackPtr = i_stacks[c++];
        KLog(Info, "Bringing up CPU #%u...", acpis[i]);
        currentBootId = acpis[i];
        KLog(Debug, "Sending INIT-IPI-1...");
        retval = __SendIPI(0xc500, &status);
        if (ESuccess != retval)
            return retval;
        KLog(Debug, "%#x\n", status);
        __UDelay(10000);
        KLog(Debug, "Sending INIT-IPI-2...");
        retval = __SendIPI(0x8500, &status);
        if (ESuccess != retval)
            return retval;
        KLog(Debug, "%#x\n", status);
        retval = CPU_ApicRead(ErrorStatus, &value);
        if (ESuccess != retval)
            return retval;
        KLog(Debug, "Sending STARTUP-IPI...");
        retval = __SendIPI(0x600 | (0x7000 >> 12), &status);
        if (ESuccess != retval)
            return retval;
        KLog(Debug, "%#x\n", status);
        __UDelay(300);
        __WaitForApic(&status);
        __UDelay(200);
        retval = CPU_ApicRead(ErrorStatus, &value);
        UInt32 accept = value & 0xef;
        if (0 == accept && 0 == status) {
            while ((UInt32)~0x0 != currentBootId) ;
            continue;
        }
        if (0 != accept)
            KLog(Error, "APIC-delivery: %#x\n", accept);
        if (0 != status)
            KLog(Error, "APIC not delivered: %#x\n", status);
        return -EBusy;
    }
    return ESuccess;
}
struct String {
    char *m_charArr;
    int m_length;
};
void myfunc(struct String* i_string, const char[] text);

