Monisuoritinjärjestelmän tunnistus

Maniace 15.07.04 15:35

Alustava tunnistus tietokoneen monisuoritinjärjestelmälle.

 Tekstiversio  Arvo: 2 (2 ääntä)  Äänestä: +  -
// Tavallista C-koodia, luonnollisesti funktiot joita tässä kutsutaan ovat
// käyttöjärjestelmäkohtaisia ja omassa
// järjestelmässäsi sinun pitää kirjoittaa ne itse. Ja päivän selvää kai on, että tätä
// koodia on aika hankala
// ajaa missään muussa käyttöjärjestelmässä kuin omassasi/DOSissa.

typedef UCHAR unsigned char;
typedef USHORT unsigned short int;
typedef ULONG unsigned long int;

#define MAX_PROCESSORS      20
#define MAX_IOAPICS         20

#define ENTRYID_PROCESSOR   0
#define ENTRYID_BUS         1
#define ENTRYID_IOAPIC      2     // I/O APIC
#define ENTRYID_IOIA        3     // I/O Interrupt Assignment
#define ENTRYID_LIA         4     // Local Interrupt Assignment

// For multiprocessing - BSP LAPIC register memory addresses
#define LAPIC_ID                            0x20            // R/W
#define LAPIC_IDVERSION                     0x30            // R
#define LAPIC_PRIORITY_TASK                 0x80            // R/W
#define LAPIC_PRIORITY_ARBITRATION          0x90            // R
#define LAPIC_PRIORITY_PROCESSOR            0xA0            // R
#define LAPIC_EOI                           0xB0            // W
#define LAPIC_DESTINATION_LOGIGAL           0xC0            // R/W
#define LAPIC_DESTINATION_FORMAT            0xE0            // Bits 0-27 Read only, Bits 28-31 Read/Write
#define LAPIC_INTERRUPT_SPURIOUS            0xF0            // Bits 0-3 Read only, Bits 4-9 Read/Write
#define LAPIC_ISR_START                     0x100           // 255 Read-only Entries
#define LAPIC_TMR_START                     0x180           // 255 Read-only Entries
#define LAPIC_IRR_START                     0x200           // 255 Read-only Entries
#define LAPIC_STATUS_ERROR                  0x280           // R
#define LAPIC_ICR32                         0x300           // R/W, First 32 Interrupt command registers
#define LAPIC_ICR64                         0x310           // R/W, Interrupt command registers 31-63
#define LAPIC_LVT_TIMER                     0x320           // R/W
#define LAPIC_LVT_COUNTER_PERFORMANCE       0x340           // R/W
#define LAPIC_LVT_LINT0                     0x350           // R/W
#define LAPIC_LVT_LINT1                     0x360           // R/W
#define LAPIC_LVT_ERROR                     0x370           // R/W
#define LAPIC_TIMER_COUNT_INITIAL           0x380           // R/W
#define LAPIC_TIMER_COUNT_CURRENT           0x390           // R
#define LAPIC_TIMER_DIVIDE_CONFIGURATION    0x3E0           // R/W

typedef struct {        // Multiprocessor structure
   UCHAR signature[4];
   ULONG *MPConfig;
   UCHAR length, version, checksum, MPFeatures1, MPFeatures2,
        MPFeatures3, MPFreatures4, MPFreatures5;
} MPS;

typedef struct {        // Multiprocessor Configuration Table
   UCHAR Signature[4];
   USHORT BaseTableLength;
   UCHAR Revision, BaseTableChecksum;
   UCHAR OEMID[8], ProductID[12];
   ULONG OEMTable;
   USHORT OEMTableSize, EntryCount;
   ULONG LAPIC;
   USHORT ExtendedTableLength;
   UCHAR ExtendedTableChecksum;
} MPTABLE;

typedef struct {       // Multiprocessing Processor Entry
   UCHAR EntryType, LocalAPICID, LocalAPICVersion, CPUInfo;
   ULONG Signature, FeatureFlags;
} ENTRY_PROCESSOR;

typedef struct {       // Multiprocessing I/O APIC Entry
   UCHAR EntryType, ID, Version, Info;
   ULONG Address;
} ENTRY_IOAPIC;

typedef struct {
   ULONG MaxEAX;
   UCHAR VendorSign[13];
   ULONG BitMap[4];
   ULONG MHz;
} PROCESSOR;

typedef struct {
   ULONG Address;
} IOAPIC;


char *Comp1[32];

unsigned long int mp_system = 0;
unsigned char *mp_magic = "_MP_";
unsigned char *mp_signature = "PCMP";
unsigned long Processors = 0, IOAPICs = 0;

ENTRY_PROCESSOR *ProcessorEntry[MAX_PROCESSORS];
ENTRY_IOAPIC *IOAPICEntry[MAX_IOAPICS];
PROCESSOR Processor[MAX_PROCESSORS];
IOAPIC IoApic[MAX_IOAPICS];

UCHAR *propelli = "-\\|/-\\|/";

void initprocessors(void) {
   unsigned long loop, address;
   MPS *Mps;
   MPTABLE *MPTable;
   unsigned char type;

   // Slows down, but I have bored & I want to play with my graphics routines :)
   unsigned long rotatecount = 0, angle = 0;

   printf("Scanning processors... ");

   // Scan last KB of Base Memory for Multi Processor Structure
   for (loop = 639 * 1024; loop < 640 * 1024; loop++) {
      rotatecount++;

      if (rotatecount == 500) {
         printf("%c\b", propelli[angle++]);
         if (angle == 8) angle = 0;
         rotatecount = 0;
      }

      if (!memcmp(loop, (ULONG)mp_magic, strlen(mp_magic))) {
         mp_system = 1;
         (ULONG)Mps = (ULONG)loop;
         (ULONG)MPTable = (ULONG)Mps->MPConfig;
      }
   }

   // Scan BIOS ROM address space for Multi Processor Structure
   for (loop = 0xF0000; loop < 0xFFFFF; loop++) {
      rotatecount++;

      if (rotatecount == 500) {
         printf("%c\b", propelli[angle++]);
         if (angle == 8) angle = 0;
         rotatecount = 0;
      }

      if (!memcmp(loop, (ULONG)mp_magic, strlen(mp_magic))) {
         mp_system = 1;
         (ULONG)Mps = (ULONG)loop;
         (ULONG)MPTable = (ULONG)Mps->MPConfig;
      }
   }

   printf(" \n\r");

   // FIXME: Add scan for BIOS Extended ROM */
   // FIXME: Add scan for top of physical memory
   // FIXME: Add checksum check

   // Store local apic address

   printf("%s initialization: ", mp_system ? "Multiprocessor" : "Uniprocessor");
   if (mp_system) {
      if (memcmp((ULONG)MPTable->Signature, (ULONG)mp_signature, strlen(mp_signature)))
         printf("\n\rWarning: MP Configuration table signature incorrect.\n\r");


      // Are we in Bochs? :)

      if (!memcmp((ULONG)MPTable->OEMID, (ULONG)"BOCHS", 5))
      printf("What is the Matrix?\n\r");



      address = (ULONG)MPTable + sizeof(MPTABLE);

      for (loop = 0; loop < MPTable->EntryCount; loop++) {
         switch(peekb(LINEAR_SEL, address)) {
            case ENTRYID_PROCESSOR:
               (ULONG)ProcessorEntry[Processors++] = address;
               address += 20;
               break;
            case ENTRYID_BUS:
               address += 8;
               break;
            case ENTRYID_IOAPIC:
               (ULONG)IOAPICEntry[IOAPICs] = address;
               if (!IOAPICEntry[IOAPICs]->Address)
                  IoApic[IOAPICs++].Address = 0xFEC00000;
               address += 8;
               break;
            case ENTRYID_IOIA:
               address += 8;
               break;
            case ENTRYID_LIA:
               address += 8;
               break;
            default:
               printf("\n\rWarning: Unknown MP Entry %i at 0x%x\n\r", peekb(LINEAR_SEL,

address), address);
               break;
         }
      }

      printf("%i processors, MP version 1.%i\n\r", Processors, MPTable->Revision);
      printf("Enabling BSP LAPIC... ");

      // Enable BSP LAPIC
      // FIXME: Make LAPIC handling primitives

      poked(LINEAR_SEL, LAPIC_INTERRUPT_SPURIOUS, setbit(peekd(LINEAR_SEL,

LAPIC_INTERRUPT_SPURIOUS), 23, 1));
      printf("Done.\n\r");
      printf("Sorry, no further support for MP systems.\n\r");
   } else {
      Processors = 1;
      printf("UniProcessor system.\n\r");
      // Alla oleva koodi vaatii CPUID-funktion, jonka laitan tänne ehkä tulevaisuudessa.


      CPUID(&Processor[0]);

      switch (((Processor[0].BitMap[0] >> 12) & 0x7)) {
         case 0:
            printf("Original ");
            break;
         case 1:
            printf("OverDrive ");
            break;
         case 2:
            printf("Dual ");
            break;
      }

      printf("%s\n\r", Processor[0].VendorSign);
   }

}



 

Maniace 15:37 15.7.04 
Juuh, ensimmäiset kommentit on vähän persiillään, mutta eipä kai tuo haittaa. Koodi on revitty suoraan omasta käyttöjärjestelmästäni.
thefox 01:22 16.7.04 
Lienee jotain bugia tuossa C-koodin värjäyksessä tai yleensäkkin näytössä kun kenoviiva näyttää kertautuvan.

Vaikuttaisi ihan kelpo vinkiltä, itse en tuollaista ole toteuttanut niin en sinänsä osaa sanoa juuta tai jaata mutta kai tuo toimii :) Käytitkö kenties jotain dokumenttia apuna tätä tehdessäsi ja jos niin mitä?
Maniace 11:28 16.7.04 
Juu tosiaan tossa propellissa pitäis olla kenoviivojen kohdalla vaan "\\", ei "\\\\". Ja hoksasin tuossa, että noi CPUID-tulostukset ei toimi, koska toi CPUID-on assembly-funktio.

En käyttänyt muutakun Googlee ja tutoriaaleja, mitä tuolta osdever.netistä löyty.
Akiro 11:32 16.7.04 
Itse olet kädettäny jotain, hyvin nuo \ ja \\ toimii tuossa, katso vaikka muita koodipätkiä. Muokkaapas ne kuntoon.

PS. Sähän laitoit tuon eilen johonkin omaan pasteviritykseesi tuon, ettei vaan siinä olisi tullut extra-kenoja mukan ;-)
Maniace 22:01 16.7.04 
Siitä ne tuli, en mä muuta väittänytkään ;)
Maniace 22:09 16.7.04 
Mutta mä väitän, että teidän muokkaus ei toimi.