X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_mptable.c;h=4b21fccf71c6a8a4d4b10f4e4412fd29a35a66c3;hb=fc220749dd74a84f222b4a60c69a47e6ae743990;hp=efef7eab8b7549ca231556135bc7df19192769f8;hpb=8300df0450154d7a2db08a7afbd2aca32ce38f70;p=palacios.git diff --git a/palacios/src/palacios/vmm_mptable.c b/palacios/src/palacios/vmm_mptable.c index efef7ea..4b21fcc 100644 --- a/palacios/src/palacios/vmm_mptable.c +++ b/palacios/src/palacios/vmm_mptable.c @@ -49,7 +49,7 @@ #define POINTER_SIGNATURE "_MP_" #define HEADER_SIGNATURE "PCMP" -#define SPEC_REV ((uchar_t)0x4) +#define SPEC_REV ((uint8_t)0x4) #define OEM_ID "V3VEE " #define PROD_ID "PALACIOS 1.3 " @@ -94,91 +94,99 @@ // This points to the mp table header struct mp_floating_pointer { - uint32_t signature; // "_MP_" - uint32_t pointer; // gpa of MP table (0xfcc00) - uint8_t length; - uint8_t spec_rev; // 0x4 - uint8_t checksum; - uint8_t mp_featurebyte[5]; // zero out to indicate mp config table - // first byte nonzero => default configurations (see spec) - // second byte, bit 7 (top bit) = IMCR if set, virtual wire if zero + uint32_t signature; /* "_MP_" */ + uint32_t pointer; /* gpa of MP table (0xfcc00) */ + uint8_t length; /* length in 16 byte chunks (paragraphs) */ + uint8_t spec_rev; /* 0x4 */ + uint8_t checksum; + uint8_t mp_featurebyte[5]; /* zero out to indicate mp config table + first byte nonzero => default configurations (see spec) + second byte, bit 7 (top bit) = IMCR if set, virtual wire if zero */ } __attribute__((packed)); struct mp_table_header { - uint32_t signature; // "PCMP" - uint16_t base_table_length; // bytes, starting from header - uint8_t spec_rev; // specification rvision (0x4 is the current rev) - uint8_t checksum; // sum of all bytes, including checksum, must be zero - uint8_t oem_id[8]; // OEM ID "V3VEE " - uint8_t prod_id[12]; // Product ID "PALACIOS 1.3" - uint32_t oem_table_ptr; // oem table, if used (zeroed) - uint16_t oem_table_size; // oem table length, if used - uint16_t entry_count; // numnber of entries in this table - uint32_t lapic_addr; // apic address on all processors - uint16_t extended_table_length; // zero by default - uint8_t extended_table_checksum; // zero by default - // this is followed by entries of the various types indicated below + uint32_t signature; /* "PCMP" */ + uint16_t base_table_length; /* bytes, starting from header */ + uint8_t spec_rev; /* specification rvision (0x4 is the current rev) */ + uint8_t checksum; /* sum of all bytes, including checksum, must be zero */ + uint8_t oem_id[8]; /* OEM ID "V3VEE " */ + uint8_t prod_id[12]; /* Product ID "PALACIOS 1.3" */ + uint32_t oem_table_ptr; /* oem table, if used (zeroed) */ + uint16_t oem_table_size; /* oem table length, if used */ + uint16_t entry_count; /* numnber of entries in this table */ + uint32_t lapic_addr; /* apic address on all processors */ + uint16_t extended_table_length; /* zero by default */ + uint8_t extended_table_checksum; /* zero by default */ + uint8_t reserved; /* zero by default */ + /* this is followed by entries of the various types indicated below */ } __attribute__((packed)); struct mp_table_processor { uint8_t entry_type; // type 0 uint8_t lapic_id; // 0.. uint8_t lapic_version; // + union { uint8_t data; struct { - uint8_t en:1; // 1=processor enabled - uint8_t bp:1; // 1=bootstrap processor - uint8_t reserved:6; - } fields; - } cpu_flags; + uint8_t en : 1; /* 1 = processor enabled */ + uint8_t bp : 1; /* 1 = bootstrap processor */ + uint8_t reserved : 6; + } __attribute__((packed)); + } __attribute__((packed)) cpu_flags; + union { uint32_t data; struct { - uint8_t stepping:4; - uint8_t model:4; - uint8_t family:4; - uint32_t rest:20; - } fields; - } cpu_signature; - uint32_t cpu_feature_flags; // result of CPUID + uint8_t stepping : 4; + uint8_t model : 4; + uint8_t family : 4; + uint32_t rest : 20; + } __attribute__((packed)); + } __attribute__((packed)) cpu_signature; + + uint32_t cpu_feature_flags; /* result of CPUID */ uint32_t reserved[2]; } __attribute__((packed)); struct mp_table_bus { - uint8_t entry_type; // type 1 - uint8_t bus_id; // 0.. - uint8_t bus_type[6]; // "PCI" "INTERN", etc + uint8_t entry_type; /* type 1 */ + uint8_t bus_id; /* 0.. */ + uint8_t bus_type[6]; /* "PCI" "INTERN", etc */ } __attribute__((packed)); struct mp_table_ioapic { - uint8_t entry_type; // type 2 - uint8_t ioapic_id; // 0.. - uint8_t ioapic_version; // bits 0..7 of the version register + uint8_t entry_type; /* type 2 */ + uint8_t ioapic_id; /* 0.. */ + uint8_t ioapic_version; /* bits 0..7 of the version register */ + union { uint8_t data; struct { - uint8_t en:1; // 1=ioapic enabled - uint8_t reserved:7; - } fields; - } ioapic_flags; - uint32_t ioapic_address; // physical address (same for all procs) + uint8_t en : 1; /* 1=ioapic enabled */ + uint8_t reserved : 7; + } __attribute__((packed)); + } __attribute__((packed)) ioapic_flags; + + uint32_t ioapic_address; /* physical address (same for all procs) */ } __attribute__((packed)); struct mp_table_io_interrupt_assignment { - uint8_t entry_type; // type 3 - uint8_t interrupt_type; // 0=int, 1=nmi, 2=smi, 3=ExtInt(8259) - union { - uint16_t data; + uint8_t entry_type; /* type 3 */ + uint8_t interrupt_type; /* 0=int, 1=nmi, 2=smi, 3=ExtInt(8259) */ + + union { + uint16_t value; struct { - uint8_t po:2; // polarity (00=default for bus, 01=active high, 10=reserved, 11=active low - uint8_t el:2; // trigger mode (00=default for bus, 01=edge, 10=reserved, 11=level) - uint16_t reserved:12; - } fields; - } io_interrupt_flags; + uint8_t po : 2; /* polarity (00 = default for bus, 01 = active high, 10 = reserved, 11 = active low */ + uint8_t el : 2; /* trigger mode (00 = default for bus, 01 = edge, 10 = reserved, 11 = level) */ + uint16_t reserved : 12; + } __attribute__((packed)); + } __attribute__((packed)) flags; + uint8_t source_bus_id; uint8_t source_bus_irq; uint8_t dest_ioapic_id; @@ -187,16 +195,18 @@ struct mp_table_io_interrupt_assignment { struct mp_table_local_interrupt_assignment { - uint8_t entry_type; // type 4 - uint8_t interrupt_type; // 0=int, 1=nmi, 2=smi, 3=ExtInt(8259) + uint8_t entry_type; /* type 4 */ + uint8_t interrupt_type; /* 0 = int, 1 = nmi, 2 = smi, 3 = ExtInt(8259) */ + union { - uint16_t data; + uint16_t value; struct { - uint8_t po:2; // polarity (00=default for bus, 01=active high, 10=reserved, 11=active low - uint8_t el:2; // trigger mode (00=default for bus, 01=edge, 10=reserved, 11=level) - uint16_t reserved:12; - } fields; - } io_interrupt_flags; + uint8_t po : 2; /* polarity (00 = default for bus, 01 = active high, 10 = reserved, 11 = active low */ + uint8_t el : 2; /* trigger mode (00 = default for bus, 01 = edge, 10 = reserved, 11 = level) */ + uint16_t reserved : 12; + } __attribute__((packed)); + } __attribute__((packed)) flags; + uint8_t source_bus_id; uint8_t source_bus_irq; uint8_t dest_ioapic_id; @@ -207,80 +217,75 @@ struct mp_table_local_interrupt_assignment { -static int check_for_cookie(void *target) -{ - return 0==memcmp(target,BIOS_MP_TABLE_COOKIE,BIOS_MP_TABLE_COOKIE_LEN); +static inline int check_for_cookie(void * target) { + return (memcmp(target, BIOS_MP_TABLE_COOKIE, BIOS_MP_TABLE_COOKIE_LEN) == 0); } -static int check_table(void *target) -{ +static inline int check_table(void * target) { uint32_t i; uint8_t sum; - struct mp_table_header *header; + struct mp_table_header * header; - V3_Print("Checksuming mptable header and entries at %p\n",target); + header = (struct mp_table_header *)target; + sum = 0; - header=(struct mp_table_header *)target; - sum=0; - for (i=0;ibase_table_length;i++) { - sum+=((uint8_t *)target)[i]; + for (i = 0; i < header->base_table_length; i++) { + sum += ((uint8_t *)target)[i]; } - if (sum==0) { - V3_Print("Checksum passed\n"); + + if (sum == 0) { return 1; } else { - V3_Print("Checksum FAILED\n"); + // failed checksum return 0; } } -static int check_pointer(void *target) -{ +static inline int check_pointer(void * target) { uint32_t i; uint8_t sum; - struct mp_floating_pointer *p; + struct mp_floating_pointer * p; - V3_Print("Checksuming mptable floating pointer at %p\n",target); + p = (struct mp_floating_pointer *)target; + sum = 0; - p=(struct mp_floating_pointer *)target; - sum=0; - for (i=0;ilength*16;i++) { - sum+=((uint8_t *)target)[i]; + for (i = 0; i < p->length * 16; i++) { + sum += ((uint8_t *)target)[i]; } - if (sum==0) { - V3_Print("Checksum passed\n"); + + if (sum == 0) { + // passed return 1; } else { - V3_Print("Checksum FAILED\n"); + // failed return 0; } } -static int write_pointer(void *target, uint32_t mptable_gpa) -{ +static int write_pointer(void * target, uint32_t mptable_gpa) { uint32_t i; uint8_t sum; - struct mp_floating_pointer *p=(struct mp_floating_pointer*)target; + struct mp_floating_pointer * p = (struct mp_floating_pointer *)target; - memset((void*)p,0,sizeof(*p)); + memset((void *)p, 0, sizeof(struct mp_floating_pointer)); - memcpy((void*)&(p->signature),POINTER_SIGNATURE,4); + memcpy((void *)&(p->signature), POINTER_SIGNATURE, 4); - p->pointer=mptable_gpa; - p->length=1; // length in 16 byte chunks - p->spec_rev=SPEC_REV; + p->pointer = mptable_gpa; + p->length = 1; // length in 16 byte chunks + p->spec_rev = SPEC_REV; // checksum calculation - p->checksum=0; - sum=0; - for (i=0;i<16;i++) { - sum+=((uint8_t *)target)[i]; + p->checksum = 0; + sum = 0; + + for (i = 0; i < 16; i++) { + sum += ((uint8_t *)target)[i]; } - p->checksum=(255-sum)+1; - V3_Print("MP Floating Pointer written to %p\n",target); + p->checksum = (255 - sum) + 1; return 0; } @@ -288,96 +293,104 @@ static int write_pointer(void *target, uint32_t mptable_gpa) -static int write_mptable(void *target, uint32_t numcores) -{ - uint32_t i; - uint8_t sum; - uint8_t core; - uint8_t irq; - uint8_t *cur; - struct mp_table_header *header; - struct mp_table_processor *proc; - struct mp_table_bus *bus; - struct mp_table_ioapic *ioapic; - struct mp_table_io_interrupt_assignment *interrupt; - - - cur=(uint8_t *)target; - header=(struct mp_table_header *)cur; - cur=cur+sizeof(*header); +static int write_mptable(void * target, uint32_t numcores) { + uint32_t i = 0; + uint8_t sum = 0; + uint8_t core = 0; + uint8_t irq = 0; + struct mp_table_header * header = NULL; + struct mp_table_processor * proc = NULL; + struct mp_table_bus * bus = NULL; + struct mp_table_ioapic * ioapic = NULL; + struct mp_table_io_interrupt_assignment * interrupt = NULL; + uint8_t * cur = target; + + header = (struct mp_table_header *)cur; + cur = cur + sizeof(struct mp_table_header); - memset((void*)header,0,sizeof(*header)); + memset((void *)header, 0, sizeof(struct mp_table_header)); - memcpy(&(header->signature),HEADER_SIGNATURE,4); - header->spec_rev=SPEC_REV; - memcpy(header->oem_id,OEM_ID,8); - memcpy(header->prod_id,PROD_ID,12); + memcpy(&(header->signature), HEADER_SIGNATURE, 4); + header->spec_rev = SPEC_REV; + memcpy(header->oem_id, OEM_ID, 8); + memcpy(header->prod_id, PROD_ID, 12); // n processors, 1 ioapic, 1 isa bus, 16 IRQs = 18+n - header->entry_count=numcores+18; - header->lapic_addr=LAPIC_ADDR; + header->entry_count = numcores + 18; + header->lapic_addr = LAPIC_ADDR; // now we arrange the processors; - for (core=0;coreentry_type=ENTRY_PROC; - proc->lapic_id=core; - proc->lapic_version=LAPIC_VERSION; - proc->cpu_flags.fields.en=1; - proc->cpu_flags.fields.bp = (core==0); - proc->cpu_signature.fields.family=PROC_FAMILY; - proc->cpu_signature.fields.model=PROC_MODEL; - proc->cpu_signature.fields.stepping=PROC_STEPPING; - proc->cpu_feature_flags=PROC_FEATURE_FLAGS; + for (core = 0; core < numcores; core++) { + proc = (struct mp_table_processor *)cur; + memset((void *)proc, 0, sizeof(struct mp_table_processor)); + proc->entry_type = ENTRY_PROC; + proc->lapic_id = core; + proc->lapic_version = LAPIC_VERSION; + proc->cpu_flags.en = 1; + + if (core == 0) { + proc->cpu_flags.bp = 1; + } else { + proc->cpu_flags.bp = 0; + } + + proc->cpu_signature.family = PROC_FAMILY; + proc->cpu_signature.model = PROC_MODEL; + proc->cpu_signature.stepping = PROC_STEPPING; + proc->cpu_feature_flags = PROC_FEATURE_FLAGS; + + cur += sizeof(struct mp_table_processor); } // next comes the ISA bas - bus=(struct mp_table_bus *)cur; - cur+=sizeof(*bus); + bus = (struct mp_table_bus *)cur; + cur += sizeof(struct mp_table_bus); - memset((void*)bus,0,sizeof(*bus)); - bus->entry_type=ENTRY_BUS; - bus->bus_id=0; - memcpy(bus->bus_type,BUS_ISA,6); + memset((void *)bus, 0, sizeof(struct mp_table_bus)); + bus->entry_type = ENTRY_BUS; + bus->bus_id = 0; + memcpy(bus->bus_type, BUS_ISA, 6); // next comes the IOAPIC - ioapic=(struct mp_table_ioapic *)cur; - cur+=sizeof(*ioapic); + ioapic = (struct mp_table_ioapic *)cur; + cur += sizeof(struct mp_table_ioapic); - memset((void*)ioapic,0,sizeof(*ioapic)); - ioapic->entry_type=ENTRY_IOAPIC; - ioapic->ioapic_id=numcores; - ioapic->ioapic_version=IOAPIC_VERSION; - ioapic->ioapic_flags.fields.en=1; - ioapic->ioapic_address=IOAPIC_ADDR; - - for (irq=0;irq<16;irq++, cur+=sizeof(*interrupt)) { - interrupt=(struct mp_table_io_interrupt_assignment *)cur; - memset((void*)interrupt,0,sizeof(*interrupt)); - interrupt->entry_type=ENTRY_IOINT; - interrupt->interrupt_type=INT_TYPE_INT; - interrupt->io_interrupt_flags.fields.po=INT_POLARITY_DEFAULT; - interrupt->io_interrupt_flags.fields.el=INT_TRIGGER_DEFAULT; - interrupt->source_bus_id=0; - interrupt->source_bus_irq=irq; - interrupt->dest_ioapic_id=1; - interrupt->dest_ioapic_intn=irq; + memset((void *)ioapic, 0, sizeof(struct mp_table_ioapic)); + ioapic->entry_type = ENTRY_IOAPIC; + ioapic->ioapic_id = numcores; + ioapic->ioapic_version = IOAPIC_VERSION; + ioapic->ioapic_flags.en = 1; + ioapic->ioapic_address = IOAPIC_ADDR; + + for (irq = 0; irq < 16; irq++) { + interrupt = (struct mp_table_io_interrupt_assignment *)cur; + memset((void *)interrupt, 0, sizeof(struct mp_table_io_interrupt_assignment)); + + interrupt->entry_type = ENTRY_IOINT; + interrupt->interrupt_type = INT_TYPE_INT; + interrupt->flags.po = INT_POLARITY_DEFAULT; + interrupt->flags.el = INT_TRIGGER_DEFAULT; + interrupt->source_bus_id = 0; + interrupt->source_bus_irq = irq; + interrupt->dest_ioapic_id = numcores; + interrupt->dest_ioapic_intn = irq; + + cur += sizeof(struct mp_table_io_interrupt_assignment); } // now we can set the length; - header->base_table_length = (cur-(uint8_t*)header); + header->base_table_length = (cur - (uint8_t *)header); // checksum calculation - header->checksum=0; - sum=0; - for (i=0;ibase_table_length;i++) { - sum+=((uint8_t *)target)[i]; + header->checksum = 0; + sum = 0; + for (i = 0; i < header->base_table_length; i++) { + sum += ((uint8_t *)target)[i]; } - header->checksum=(255-sum)+1; + header->checksum = (255 - sum) + 1; @@ -385,11 +398,10 @@ static int write_mptable(void *target, uint32_t numcores) } -int v3_inject_mptable(struct v3_vm_info *vm) -{ - void *target; +int v3_inject_mptable(struct v3_vm_info * vm) { + void * target = NULL; - if (v3_gpa_to_hva(&(vm->cores[0]),BIOS_MP_TABLE_DEFAULT_LOCATION,(addr_t*)&target)==-1) { + if (v3_gpa_to_hva(&(vm->cores[0]), BIOS_MP_TABLE_DEFAULT_LOCATION, (addr_t *)&target) == -1) { PrintError("Cannot inject mptable due to unmapped bios!\n"); return -1; } @@ -399,14 +411,14 @@ int v3_inject_mptable(struct v3_vm_info *vm) return -1; } - if (vm->num_cores>32) { + if (vm->num_cores > 32) { PrintError("No support for >32 cores in writing MP table, aborting.\n"); return -1; } - V3_Print("Starting mptable pointer, header, and entry construction for %u cores at %p\n",vm->num_cores,target); + V3_Print("Constructing mptable for %u cores at %p\n", vm->num_cores, target); - if (-1==write_pointer(target,BIOS_MP_TABLE_DEFAULT_LOCATION+sizeof(struct mp_floating_pointer))) { + if (write_pointer(target, BIOS_MP_TABLE_DEFAULT_LOCATION + sizeof(struct mp_floating_pointer)) == -1) { PrintError("Unable to write mptable floating pointer, aborting.\n"); return -1; } @@ -416,18 +428,16 @@ int v3_inject_mptable(struct v3_vm_info *vm) return -1; } - if (-1==write_mptable(target+sizeof(struct mp_floating_pointer),vm->num_cores)) { + if (write_mptable(target + sizeof(struct mp_floating_pointer), vm->num_cores) == -1) { PrintError("Cannot inject mptable configuration header and entries\n"); return -1; } - if (!check_table(target+sizeof(struct mp_floating_pointer))) { + if (!check_table(target + sizeof(struct mp_floating_pointer))) { PrintError("Failed to inject mptable configuration header and entries correctly --- checksum fails\n"); return -1; } - V3_Print("Done with mptable pointer, header, and entry construction\n"); return 0; - }