Exemple #1
0
acpi_table_header_t *mon_acpi_locate_table(char *sig)
{
	acpi_table_rsdp_t *rsdp = NULL;
	void *table = NULL;

	/* Try 0x0 first for getting rsdp table */
	rsdp = scan_for_rsdp(acpi_map_memory(0), 0x400);
	if (NULL == rsdp) {
		/* Try 0xE0000 */
		MON_LOG(mask_anonymous, level_trace,
			"Try 0xE0000 for ACPI RSDP table\n");
		rsdp = scan_for_rsdp(acpi_map_memory(0xE0000), 0x1FFFF);
	}

	if (NULL == rsdp) {
		MON_LOG(mask_anonymous,
			level_error,
			"Could not find the rsdp table\n");
		return NULL;
	}

	MON_LOG(mask_anonymous, level_trace, "rsdp address %p\n", rsdp);

	/* Get the specified table from rsdp */
	table = get_acpi_table_from_rsdp(rsdp, sig);

	return table;
}
Exemple #2
0
static const struct acpi_rsdp *find_rsdp(void)
{
    uint32_t ebda;
    const struct acpi_rsdp *rsdp;

    ebda = (*(uint16_t *)0x40e) << 4;
    if (ebda >= 0x70000 && ebda < 0xa0000) {
	rsdp = scan_for_rsdp(ebda, ebda+1024);

	if (rsdp)
	    return rsdp;
    }

    return scan_for_rsdp(0xe0000, 0x100000);
}
Exemple #3
0
/* This is where we search for SMP information in the following order
 * look for a floating MP pointer
 *   found:
 *     check for a default configuration
 * 	 found:
 *	   setup config, return
 *     check for a MP config table
 *	 found:
 *	   validate:
 *           good:
 *	        parse the MP config table
 *		  good:
 *		    setup config, return
 *
 * find & validate ACPI RSDP (Root System Descriptor Pointer)
 *   found:
 *     find & validate RSDT (Root System Descriptor Table)
 *       found:
 *         find & validate MSDT
 *	     found:
 *             parse the MADT table
 *               good:
 *		   setup config, return
 */
void smp_find_cpus()
{
   floating_pointer_struct_t *fp;
   rsdp_t *rp;
   rsdt_t *rt;
   uint8_t *tab_ptr, *tab_end;
   unsigned int *ptr;
   unsigned int uiptr;

   if(v->fail_safe & 3) { return; }

   memset(&AP, 0, sizeof AP);

	if(v->fail_safe & 8)
	{		
	   // Search for the Floating MP structure pointer
	   fp = scan_for_floating_ptr_struct(0x0, 0x400);
	   if (fp == NULL) {
	      fp = scan_for_floating_ptr_struct(639*0x400, 0x400);
	   }
	   if (fp == NULL) {
	      fp = scan_for_floating_ptr_struct(0xf0000, 0x10000);
	   }
	   if (fp == NULL) {
	        // Search the BIOS ESDS area
	        unsigned int address = *(unsigned short *)0x40E;
	        address <<= 4;
					if (address) {
	       		fp = scan_for_floating_ptr_struct(address, 0x400);
	        }
	   }
	
	   if (fp != NULL) {
				// We have a floating MP pointer
				// Is this a default configuration?
				
				if (fp->feature[0] > 0 && fp->feature[0] <=7) {
				    // This is a default config so plug in the numbers
				    num_cpus = 2;
				    APIC = (volatile apic_register_t*)0xFEE00000;
				    cpu_num_to_apic_id[0] = 0;
				    cpu_num_to_apic_id[1] = 1;
				    return;
				}
				
				// Do we have a pointer to a MP configuration table?
				if ( fp->phys_addr != 0) {
				    if (read_mp_config_table(fp->phys_addr)) {
							// Found a good MP table, done
							return;
				    }
				}
	   }
	}


   /* No MP table so far, try to find an ACPI MADT table
    * We try to use the MP table first since there is no way to distinguish
    * real cores from hyper-threads in the MADT */

   /* Search for the RSDP */
   rp = scan_for_rsdp(0xE0000, 0x20000);
   if (rp == NULL) {
        /* Search the BIOS ESDS area */
        unsigned int address = *(unsigned short *)0x40E;
        address <<= 4;
				if (address) {
       		rp = scan_for_rsdp(address, 0x400);
        }
   }
    
   if (rp == NULL) {
		/* RSDP not found, give up */
		return;
   }

   /* Found the RSDP, now get either the RSDT or XSDT */
   if (rp->revision >= 2) {
			rt = (rsdt_t *)rp->xrsdt[0];
			
			if (rt == 0) {
				return;
			}
			// Validate the XSDT 
			if (*(unsigned int *)rt != XSDTSignature) {
				return;
			}
			if ( checksum((unsigned char*)rt, rt->length) != 0) {
				return;
			}
			
    } else {
			rt = (rsdt_t *)rp->rsdt;
			if (rt == 0) {
				return;
			}
			/* Validate the RSDT */
			if (*(unsigned int *)rt != RSDTSignature) {
				return;
			}
			if ( checksum((unsigned char*)rt, rt->length) != 0) {
				return;
			}
    }

    /* Scan the RSDT or XSDT for a pointer to the MADT */
    tab_ptr = ((uint8_t*)rt) + sizeof(rsdt_t);
    tab_end = ((uint8_t*)rt) + rt->length;

    while (tab_ptr < tab_end) {

		uiptr = *((unsigned int *)tab_ptr);
		ptr = (unsigned int *)uiptr;

			/* Check for the MADT signature */
			if (ptr && *ptr == MADTSignature) {
		    /* Found it, now parse it */
		    if (parse_madt((uintptr_t)ptr)) {
					return;
		    }
			}
      tab_ptr += 4;
    }
}