コード例 #1
0
ファイル: smp.c プロジェクト: Einheri/wl500g
/*
 * First C code run on the secondary CPUs after being started up by
 * the master.
 */
asmlinkage __cpuinit void start_secondary(void)
{
	unsigned int cpu;

#ifdef CONFIG_MIPS_MT_SMTC
	/* Only do cpu_probe for first TC of CPU */
	if ((read_c0_tcbind() & TCBIND_CURTC) == 0)
#endif /* CONFIG_MIPS_MT_SMTC */
	cpu_probe();
	cpu_report();
	per_cpu_trap_init();
	prom_init_secondary();

	/*
	 * XXX parity protection should be folded in here when it's converted
	 * to an option instead of something based on .cputype
	 */

	calibrate_delay();
	preempt_disable();
	cpu = smp_processor_id();
	cpu_data[cpu].udelay_val = loops_per_jiffy;

	prom_smp_finish();

	cpu_set(cpu, cpu_callin_map);

	cpu_idle();
}
コード例 #2
0
asmlinkage void __init
init_arch(int argc, char **argv, char **envp, int *prom_vec)
{
	unsigned int s;

	/* Determine which MIPS variant we are running on. */
	cpu_probe();

	prom_init(argc, argv, envp, prom_vec);

#ifdef CONFIG_SGI_IP22
	sgi_sysinit();
#endif

	cpu_report();

	/*
	 * Determine the mmu/cache attached to this machine,
	 * then flush the tlb and caches.  On the r4xx0
	 * variants this also sets CP0_WIRED to zero.
	 */
	loadmmu();

	/* Disable coprocessors and set FPU for 16/32 FPR register model */
	clear_cp0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR);
	set_cp0_status(ST0_CU0);

	start_kernel();
}
コード例 #3
0
ファイル: setup.c プロジェクト: cilynx/dd-wrt
void __init setup_arch(char **cmdline_p)
{
	cpu_probe();
	prom_init();

#ifdef CONFIG_EARLY_PRINTK
	{
		extern void setup_early_printk(void);

		setup_early_printk();
	}
#endif
	cpu_report();

#if defined(CONFIG_VT)
#if defined(CONFIG_VGA_CONSOLE)
	conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
	conswitchp = &dummy_con;
#endif
#endif

	arch_mem_init(cmdline_p);

	resource_init();
#ifdef CONFIG_SMP
	plat_smp_setup();
#endif
}
コード例 #4
0
ファイル: smp.c プロジェクト: 1x23/unifi-gpl
/*
 * First C code run on the secondary CPUs after being started up by
 * the master.
 */
asmlinkage void start_secondary(void)
{
	unsigned int cpu;

	cpu_probe();
	cpu_report();
	per_cpu_trap_init();
	prom_init_secondary();

	/*
	 * XXX parity protection should be folded in here when it's converted
	 * to an option instead of something based on .cputype
	 */

	calibrate_delay();
	preempt_disable();
	cpu = smp_processor_id();
	cpu_data[cpu].udelay_val = loops_per_jiffy;

	prom_smp_finish();

	cpu_set(cpu, cpu_callin_map);

	cpu_idle();
}
コード例 #5
0
/*
 * First C code run on the secondary CPUs after being started up by
 * the master.
 */
asmlinkage void start_secondary(void)
{
	unsigned int cpu;

	cpu_probe();
	cpu_report();
	per_cpu_trap_init();
	prom_init_secondary();

	/*
	 * XXX parity protection should be folded in here when it's converted
	 * to an option instead of something based on .cputype
	 */

#ifndef CONFIG_CPU_CAVIUM_OCTEON
    /* There is no reason to waste time doing this on Octeon. All the cores
        are on the same chip and are the same speed by definition */
	calibrate_delay();
#endif
	preempt_disable();
	cpu = smp_processor_id();
	cpu_data[cpu].udelay_val = loops_per_jiffy;

	prom_smp_finish();

	cpu_set(cpu, cpu_callin_map);

	cpu_idle();
}
コード例 #6
0
ファイル: main_entry.c プロジェクト: woodsts/barebox
/**
 * Called plainly from assembler code
 *
 * @note The C environment isn't initialized yet
 */
void __bare_init main_entry(void *fdt, u32 fdt_size)
{
	unsigned long malloc_start, malloc_end;
	/* clear the BSS first */
	memset(__bss_start, 0x00, __bss_stop - __bss_start);

	cpu_probe();

	if (cpu_has_4k_cache) {
		extern void r4k_cache_init(void);

		r4k_cache_init();
	}

	trap_init();

	malloc_end = _stext;

	if (MALLOC_SIZE > 0)
		malloc_start = malloc_end - MALLOC_SIZE;
	else
		malloc_start = malloc_end - SZ_8M;

	pr_debug("initializing malloc pool at 0x%08lx (size 0x%08lx)\n",
			malloc_start, malloc_end - malloc_start);

	mem_malloc_init((void *)malloc_start, (void *)_stext - 1);
	mips_stack_top = malloc_start;

	glob_fdt = fdt;
	glob_fdt_size = fdt_size;

	start_barebox();
}
コード例 #7
0
asmlinkage void __init init_arch(int argc, char **argv, char **envp,
	int *prom_vec)
{
	/* Determine which MIPS variant we are running on. */
	cpu_probe();

	prom_init(argc, argv, envp, prom_vec);

	cpu_report();

	/*
	 * Determine the mmu/cache attached to this machine, then flush the
	 * tlb and caches.  On the r4xx0 variants this also sets CP0_WIRED to
	 * zero.
	 */
	load_mmu();

	/*
	 * On IP27, I am seeing the TS bit set when the kernel is loaded.
	 * Maybe because the kernel is in ckseg0 and not xkphys? Clear it
	 * anyway ...
	 */
	clear_c0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3);
	set_c0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR);

	start_kernel();
}
コード例 #8
0
void __init setup_arch(char **cmdline_p)
{
	/* the variable later on will be used in macros as well */
	is_nlm_xlp2xx_compat = is_nlm_xlp2xx();

	cpu_probe();
	prom_init();
#ifdef CONFIG_EARLY_PRINTK
	setup_early_printk();
#endif
	cpu_report();
	check_bugs_early();

#if defined(CONFIG_VT)
#if defined(CONFIG_VGA_CONSOLE)
	conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
	conswitchp = &dummy_con;
#endif
#endif

	arch_mem_init(cmdline_p);

	resource_init();
	plat_smp_setup();
}
コード例 #9
0
__initfunc(unsigned long
device_scan(unsigned long mem_start))
{
	char node_str[128];
	int nd, prom_node_cpu, thismid;
	int cpu_nds[NR_CPUS];  /* One node for each cpu */
	int cpu_ctr = 0;

	prom_getstring(prom_root_node, "device_type", node_str, sizeof(node_str));

	if(strcmp(node_str, "cpu") == 0) {
		cpu_nds[0] = prom_root_node;
		linux_cpus[0].prom_node = prom_root_node;
		linux_cpus[0].mid = 0;
		cpu_ctr++;
	} else {
		int scan;
		scan = prom_getchild(prom_root_node);
		prom_printf("root child is %08x\n", (unsigned) scan);
		nd = 0;
		while((scan = prom_getsibling(scan)) != 0) {
			prom_getstring(scan, "device_type", node_str, sizeof(node_str));
			if(strcmp(node_str, "cpu") == 0) {
				cpu_nds[cpu_ctr] = scan;
				linux_cpus[cpu_ctr].prom_node = scan;
				prom_getproperty(scan, "upa-portid",
						 (char *) &thismid, sizeof(thismid));
				linux_cpus[cpu_ctr].mid = thismid;
#ifdef __SMP__				
				prom_printf("Found CPU %d (node=%08x,mid=%d)\n",
					    cpu_ctr, (unsigned) scan,
					    thismid);
				printk("Found CPU %d (node=%08x,mid=%d)\n",
				       cpu_ctr, (unsigned) scan, thismid);
#endif				       
				cpu_ctr++;
			}
		};
		if(cpu_ctr == 0) {
			prom_printf("No CPU nodes found, cannot continue.\n");
			prom_halt();
		}
#ifdef __SMP__		
		printk("Found %d CPU prom device tree node(s).\n", cpu_ctr);
#endif		
	};
	prom_node_cpu = cpu_nds[0];

	linux_num_cpus = cpu_ctr;
	
	prom_cpu_nodes[0] = prom_node_cpu;

	cpu_probe();
	return central_probe(mem_start);
}
コード例 #10
0
ファイル: test.c プロジェクト: joncampbell123/doslib
int main() {
#if TARGET_MSDOS == 16
    cpu_probe();
    probe_dos();
    printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF);
    if (detect_windows()) {
        printf("I am running under Windows.\n");
        printf("    Mode: %s\n",windows_mode_str(windows_mode));
        printf("    Ver:  %x.%02u\n",windows_version>>8,windows_version&0xFF);
    }
    else {
コード例 #11
0
ファイル: ntvdmiam.c プロジェクト: joncampbell123/doslib
int i_am_ntvdm_client() {
	probe_dos();
	if (cpu_basic_level < 0) cpu_probe();
	detect_windows();

#if defined(TARGET_WINDOWS)
	/* WINE (Wine Is Not an Emulator) tends to run the code in
	 * a more direct fashion */
	if (windows_emulation == WINEMU_WINE)
		return 0;
#endif

	if (windows_mode == WINDOWS_NT)
		return 1;

	return 0;
}
コード例 #12
0
/**
 * Called plainly from assembler code
 *
 * @note The C environment isn't initialized yet
 */
void main_entry(void)
{
	/* clear the BSS first */
	memset(__bss_start, 0x00, __bss_stop - __bss_start);

	cpu_probe();

	if (cpu_has_4k_cache) {
		extern void r4k_cache_init(void);

		r4k_cache_init();
	}

	trap_init();

	start_barebox();
}
コード例 #13
0
ファイル: setup.c プロジェクト: NieHao/Tomato-RAF
asmlinkage void __init init_arch(int argc, char **argv, char **envp,
	int *prom_vec)
{
	/* Determine which MIPS variant we are running on. */
	cpu_probe();

	prom_init(argc, argv, envp, prom_vec);

	cpu_report();

	/*
	 * Determine the mmu/cache attached to this machine, then flush the
	 * tlb and caches.  On the r4xx0 variants this also sets CP0_WIRED to
	 * zero.
	 */
	load_mmu();

	start_kernel();
}
コード例 #14
0
asmlinkage void __init
init_arch(int argc, char **argv, char **envp, int *prom_vec)
{
	/* Determine which MIPS variant we are running on. */
	unsigned int s;
#ifdef CONFIG_RTL865X
	char chipVersion[16]={0};
	int rev;
	GetChipVersion(chipVersion,sizeof(chipVersion), &rev);
	printk("************************************\n");
	printk("Powered by Realtek RTL%s SoC, rev %d\n",chipVersion, rev);
	printk("************************************\n");
#endif

#ifdef CONFIG_RTL8186
	printk("************************************\n");
	printk("Powered by Realtek RTL8186 SoC\n");
	printk("************************************\n");
#endif

	cpu_probe();

	prom_init(argc, argv, envp, prom_vec);

	cpu_report();

	/*
	 * Determine the mmu/cache attached to this machine,
	 * then flush the tlb and caches.  On the r4xx0
	 * variants this also sets CP0_WIRED to zero.
	 */
#ifdef CONFIG_RTL865X
	printk("Init MMU (16 entries)\n");
#endif
	load_mmu();

	/* Disable coprocessors and set FPU for 16/32 FPR register model */
	clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR);
	set_c0_status(ST0_CU0);

	start_kernel();
}
コード例 #15
0
ファイル: gr_add.c プロジェクト: joncampbell123/doslib
int main() {
	cpu_probe();

	printf("Testing ADDw x+y (%u <= x <= %u)+(%u <= y <= %u)\n",min_i,max_i,min_j,max_j);
	grind_ADDw();
	log_close();

	printf("Testing SUBw x-y (%u <= x <= %u)+(%u <= y <= %u)\n",min_i,max_i,min_j,max_j);
	grind_SUBw();
	log_close();

	printf("Testing MULw x*y (%u <= x <= %u)+(%u <= y <= %u)\n",min_i,max_i,min_j,max_j);
	grind_MULw();
	log_close();

	printf("Testing DIVw x*y (%u <= x <= %u)+(%u <= y <= %u)\n",min_i,max_i,min_j,max_j);
	grind_DIVw();
	log_close();
	return 0;
}
コード例 #16
0
ファイル: setup.c プロジェクト: ivucica/linux
void __init setup_arch(char **cmdline_p)
{
	cpu_probe();
	prom_init();
	cpu_report();

#if defined(CONFIG_VT)
#if defined(CONFIG_VGA_CONSOLE)
        conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
        conswitchp = &dummy_con;
#endif
#endif

	arch_mem_init(cmdline_p);

	resource_init();
#ifdef CONFIG_SMP
	plat_smp_setup();
#endif
}
コード例 #17
0
ファイル: smp.c プロジェクト: iPodLinux/linux-2.4.24-ipod
/*
 * Hook for doing final board-specific setup after the generic smp setup
 * is done
 */
asmlinkage void start_secondary(void)
{
	unsigned int cpu = smp_processor_id();

	cpu_probe();
	prom_init_secondary();
	per_cpu_trap_init();

	/*
	 * XXX parity protection should be folded in here when it's converted
	 * to an option instead of something based on .cputype
	 */
	pgd_current[cpu] = init_mm.pgd;
	cpu_data[cpu].udelay_val = loops_per_jiffy;
	prom_smp_finish();
	printk("Slave cpu booted successfully\n");
	CPUMASK_SETB(cpu_online_map, cpu);
	atomic_inc(&cpus_booted);
	while (!atomic_read(&smp_commenced));
	cpu_idle();
}
コード例 #18
0
ファイル: main.c プロジェクト: LastRitter/GridOS
void hal_arch_init(int step)
{
	switch(step)
	{
	case HAL_ARCH_INIT_PHASE_EARLY:
		//plat_setup_serial();
//		video_init_screen();
//		plat_setup_ioport();
		/* Init the boot cpu, the secondary cpu should also probe it self when started */
		cpu_probe();
		arch_trap_init();
		mips_setup_traps();
		break;
	case HAL_ARCH_INIT_PHASE_MIDDLE:
		arch_init_irq();
		arch_init_smp();
		break;
	case HAL_ARCH_INIT_PHASE_LATE:
		smp_boot_aps();
		break;
	}
}
コード例 #19
0
ファイル: rdtsc.c プロジェクト: joncampbell123/doslib
int main(int argc,char *argv[],char *envp[]) {
	rdtsc_t start,measure,ticks_per_sec;
    unsigned char force = 0;
	double t;
	int c;

    {
        int i = 1;
        char *a;

        while (i < argc) {
            a = argv[i++];

            if (*a == '-') {
                do { a++; } while (*a == '-');

                if (!strcmp(a,"f") || !strcmp(a,"force"))
                    force = 1;
                else
                    return 1;
            }
            else {
                return 1;
            }
        }
    }

	cpu_probe();
	printf("Your CPU is basically a %s or higher\n",cpu_basic_level_to_string(cpu_basic_level));
	if (cpu_v86_active)
		printf(" - Your CPU is currently running me in virtual 8086 mode\n");

    if (force) {
        printf(" - You're forcing me to use RDTSC. I may crash if your CPU doesn't\n");
        printf("   support it or the environment doesn't enable it.\n");
        printf("   OK! Here we go....!\n");
    }
    else {
        if (!(cpu_flags & CPU_FLAG_CPUID)) {
            printf(" - Your CPU doesn't support CPUID, how can it support RDTSC?\n");
            return 1;
        }

        if (!(cpu_cpuid_features.a.raw[2] & 0x10)) {
            printf(" - Your CPU does not support RDTSC\n");
            return 1;
        }

        if (cpu_flags & CPU_FLAG_DONT_USE_RDTSC) {
            printf(" - Your CPU does support RDTSC but it's not recommended in this environment.\n");
            printf("   This is usually due to running a 16-bit build in pure DOS under EMM386.EXE.\n");
            return 1;
        }
    }

#if defined(TARGET_OS2)
# if TARGET_MSDOS == 32
	/* OS/2 32-bit: We can use DosQuerySysInfo() */
	printf("Measuring CPU speed, using DosQuerySysInfo(), over 3 seconds\n");
	{
		ULONG startTick,tmp;
		start = cpu_rdtsc();
		startTick = GetMsCount();
		do { tmp = GetMsCount();
		} while ((tmp - startTick) < 3000); /* NTS: <- I know this rolls over in 49 days,
		the math though should overflow the 32-bit integer and produce correct results anyway */
		measure = cpu_rdtsc();

		/* use the precise tick count to better compute ticks_per_sec */
		ticks_per_sec = ((measure - start) * 1000ULL) / ((rdtsc_t)(tmp - startTick));
		printf("Measurement: %lums = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
		printf("             From 0x%llX to 0x%llX\n",start,measure);
	}
# else
	/* OS/2 16-bit: There is no API (that I know of) to get tick count. Use system clock. */
	printf("Measuring CPU speed, using system clock with 1-second resolution, across 3 seconds\n");
	{
		time_t startTick,tmp;

		/* wait for the immediate start of a one-second tick, then record RDTSC and count until 3 seconds */
		startTick = time(NULL);
		do { tmp = time(NULL); } while (tmp == startTick);
		start = cpu_rdtsc(); startTick = tmp;

		/* NOW! Count 3 seconds and measure CPU ticks */
		do { tmp = time(NULL);
		} while ((tmp - startTick) < 3);
		measure = cpu_rdtsc();

		/* use the precise tick count to better compute ticks_per_sec */
		ticks_per_sec = ((measure - start) * 1ULL) / ((rdtsc_t)(tmp - startTick));
		printf("Measurement: %lu seconds = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
		printf("             From 0x%llX to 0x%llX\n",start,measure);
	}
# endif
#elif defined(TARGET_WINDOWS)
# if TARGET_MSDOS == 16
	/* Windows 2.x/3.0/3.1: Use GetTickCount() or
	 * Windows 3.1: Use TOOLHELP.DLL TimerCount() which is more accurate (really?) */
	if (ToolHelpInit()) {
		TIMERINFO ti;

		ti.dwSize = sizeof(ti);
		printf("Measuring CPU speed, using TOOLHELP TimerCount() over 1 second\n");
		{
			DWORD startTick,tmp;
			start = cpu_rdtsc();
			if (!__TimerCount(&ti)) {
				printf("TimerCount() failed\n");
				return 1;
			}
			startTick = ti.dwmsSinceStart;
			do {
#  if defined(WIN_STDOUT_CONSOLE)
				_win_pump(); /* <- you MUST call this. The message pump must run, or else the timer won't advance and this loop will run forever.
			                           The fact that GetTickCount() depends on a working message pump under Windows 3.1 seems to be a rather serious
						   oversight on Microsoft's part. Note that the problem described here does not apply to Windows 9x/ME. Also note
						   the Toolhelp function TimerCount() relies on GetTickCount() as a basic for time (though Toolhelp uses VxD services
						   or direct I/O port hackery to refine the timer count) */
#  endif

				if (!__TimerCount(&ti)) {
					printf("TimerCount() failed\n");
					return 1;
				}

				tmp = ti.dwmsSinceStart;
			} while ((tmp - startTick) < 1000); /* NTS: <- I know this rolls over in 49 days,
			the math though should overflow the 32-bit integer and produce correct results anyway */
			measure = cpu_rdtsc();

			/* use the precise tick count to better compute ticks_per_sec */
			ticks_per_sec = ((measure - start) * 1000ULL) / ((rdtsc_t)(tmp - startTick));
			printf("Measurement: %lums = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
			printf("             From 0x%llX to 0x%llX\n",start,measure);
		}
	}
	else {
# else
	{
# endif
		printf("Measuring CPU speed, using GetTickCount() over 3 second\n");
		{
			DWORD startTick,tmp;
			start = cpu_rdtsc();
			startTick = GetTickCount();
			/* NTS: Dunno yet about Windows 3.1, but Windows 95 seems to require we Yield(). If we don't, the GetTickCount() return
			 *      value never updates and we're forever stuck in a loop. */
			do {
#  if defined(WIN_STDOUT_CONSOLE)
				_win_pump(); /* <- you MUST call this. The message pump must run, or else the timer won't advance and this loop will run forever.
			                           The fact that GetTickCount() depends on a working message pump under Windows 3.1 seems to be a rather serious
						   oversight on Microsoft's part. Note that the problem described here does not apply to Windows 9x/ME */
#  endif
				tmp = GetTickCount();
			} while ((tmp - startTick) < 3000); /* NTS: <- I know this rolls over in 49 days,
			the math though should overflow the 32-bit integer and produce correct results anyway */
			measure = cpu_rdtsc();

			/* use the precise tick count to better compute ticks_per_sec */
			ticks_per_sec = ((measure - start) * 1000ULL) / ((rdtsc_t)(tmp - startTick));
			printf("Measurement: %lums = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
			printf("             From 0x%llX to 0x%llX\n",start,measure);
		}
	}
#else
	/* MS-DOS: Init the 8254 timer library for precise measurement */
	if (!probe_8254()) {
		printf("Cannot init 8254 timer\n");
		return 1;
	}

    /* DOSBox-X and most motherboards leave the PIT in a mode that counts down by 2.
     * Our code sets the counter and puts it in a mode that counts down by 1.
     * We have to do this or our wait functions exit in half the time (which explains
     * why testing this code in DOSBox-X often comes up with RDTSC running at 2x
     * normal speed. */
    write_8254_system_timer(0); /* 18.2 tick/sec on our terms (proper PIT mode) */

	printf("Measuring CPU speed (relative to 8254 timer)\n");

	_cli();
	start = cpu_rdtsc();
	t8254_wait(t8254_us2ticks(1000000));
	measure = cpu_rdtsc();
	_sti();

	printf("Measurement: 1 sec = %lld ticks\n",(int64_t)(measure - start));
	printf("             From 0x%llX to 0x%llX\n",start,measure);
	ticks_per_sec = (measure - start);
#endif

	if ((int64_t)ticks_per_sec < 0) {
		printf("Cannot determine CPU cycle count\n");
		ticks_per_sec = 100000ULL;
	}

	while (1) {
		measure = cpu_rdtsc();
		t = (double)((int64_t)(measure - start));
		t /= ticks_per_sec;

		printf("\x0D" "0x%llX = %.3f   ",measure,t);
#if !defined(WINFCON_STOCK_WIN_MAIN)
		fflush(stdout); /* FIXME: The fake console code should intercept fflush() too */
#endif

		if (kbhit()) {
			c = getch();
			if (c == 0) c = getch() << 8;

			if (c == 27)
				break;
			else if (c == 'r' || c == 'R') {
				if (c == 'r' || (cpu_flags & CPU_FLAG_DONT_WRITE_RDTSC)) {
					printf("\nI am not able to write the TSC register within this environment\nYou can force me by typing SHIFT+R, don't blame me when I crash...\n");
				}
				else {
					printf("\nUsing MSR to reset TSC to 0\n");
					/* demonstrating WRMSR to write the TSC (yes, you can!) */
					cpu_rdtsc_write(start = 0ULL);
					printf("Result: 0x%llX\n",cpu_rdtsc());
				}
			}
			else if (c == 's') {
				if (c == 's' && (cpu_flags & CPU_FLAG_DONT_WRITE_RDTSC)) {
					printf("\nI am not able to write the TSC register within this environment\nYou can force me by typing SHIFT+S, don't blame me when I crash...\n");
				}
				else {
					printf("\nUsing MSR to reset TSC to 0x123456789ABCDEF\n");
					/* demonstrating WRMSR to write the TSC (yes, you can!) */
					cpu_rdtsc_write(start = 0x123456789ABCDEFULL);
					printf("Result: 0x%llX\n",cpu_rdtsc());
				}
			}
		}
	}
	printf("\n");

	return 0;
}
コード例 #20
0
ファイル: test.c プロジェクト: joncampbell123/doslib
int main(int argc,char **argv) {
    struct acpi_rsdt_header sdth;
    acpi_memaddr_t addr;
    unsigned long i,max;
    uint32_t tmp32,tmplen;
    char tmp[32];

    for (i=1;i < (unsigned long)argc;) {
        const char *a = argv[(unsigned int)(i++)];

        if (*a == '-' || *a == '/') {
            do { a++; } while (*a == '-' || *a == '/');

            if (!strcmp(a,"?") || !strcmp(a,"h") || !strcmp(a,"help")) {
                help();
                return 1;
            }
            else if (!strcmp(a,"32")) {
                acpi_use_rsdt_32 = 1;
            }
            else {
                fprintf(stderr,"Unknown switch '%s'\n",a);
                help();
                return 1;
            }
        }
        else {
            fprintf(stderr,"Unknown arg '%s'\n",a);
            help();
            return 1;
        }
    }

    if (!probe_8254()) {
        printf("Cannot init 8254 timer\n");
        return 1;
    }
    if (!probe_8259()) {
        printf("Cannot init 8259 PIC\n");
        return 1;
    }
    cpu_probe();
    probe_dos();
    detect_windows();
#if TARGET_MSDOS == 32
    probe_dpmi();
    dos_ltp_probe();
#endif

#if TARGET_MSDOS == 16
    if (!flatrealmode_setup(FLATREALMODE_4GB)) {
        printf("Unable to set up flat real mode (needed for 16-bit builds)\n");
        printf("Most ACPI functions require access to the full 4GB range.\n");
        return 1;
    }
#endif

    if (!acpi_probe()) {
        printf("ACPI BIOS not found\n");
        return 1;
    }
    assert(acpi_rsdp != NULL);
    printf("ACPI %u.0 structure at 0x%05lX\n",acpi_rsdp->revision+1,(unsigned long)acpi_rsdp_location);

    memcpy(tmp,(char*)(&(acpi_rsdp->OEM_id)),6); tmp[6]=0;
    printf("ACPI OEM ID '%s', RSDT address (32-bit) 0x%08lX Length %lu\n",tmp,
        (unsigned long)(acpi_rsdp->rsdt_address),
        (unsigned long)(acpi_rsdp->length));
    if (acpi_rsdp->revision != 0)
        printf("   XSDT address (64-bit) 0x%016llX\n",
            (unsigned long long)(acpi_rsdp->xsdt_address));

    printf("Chosen RSDT/XSDT at 0x%08llX\n",(unsigned long long)acpi_rsdt_location);

    if (acpi_rsdt != NULL) {
        memcpy(tmp,(void*)(acpi_rsdt->signature),4); tmp[4] = 0;
        printf("  '%s': len=%lu rev=%u\n",tmp,(unsigned long)acpi_rsdt->length,
            acpi_rsdt->revision);

        memcpy(tmp,(void*)(acpi_rsdt->OEM_id),6); tmp[6] = 0;
        printf("  OEM id: '%s'\n",tmp);

        memcpy(tmp,(void*)(acpi_rsdt->OEM_table_id),8); tmp[8] = 0;
        printf("  OEM table id: '%s' rev %lu\n",tmp,
            (unsigned long)acpi_rsdt->OEM_revision);

        memcpy(tmp,(void*)(&(acpi_rsdt->creator_id)),4); tmp[4] = 0;
        printf("  Creator: '%s' rev %lu\n",tmp,
            (unsigned long)acpi_rsdt->creator_revision);
    }

    max = acpi_rsdt_entries();
    if (acpi_rsdt_is_xsdt()) {
        printf("Showing XSDT, %lu entries\n",max);
    }
    else {
        printf("Showing RSDT, %lu entries\n",max);
    }

    for (i=0;i < max;i++) {
        addr = acpi_rsdt_entry(i);
        printf(" [%lu] 0x%08llX ",i,(unsigned long long)addr);
        if (addr != 0ULL) {
            tmp32 = acpi_mem_readd(addr);
            tmplen = 0;

            memcpy(tmp,&tmp32,4); tmp[4] = 0;
            if (acpi_probe_rsdt_check(addr,tmp32,&tmplen)) {
                acpi_memcpy_from_phys(&sdth,addr,sizeof(struct acpi_rsdt_header));

                printf("'%s' len=0x%lX rev=%u ",tmp,(unsigned long)tmplen,sdth.revision);

                memcpy(tmp,&sdth.OEM_id,6); tmp[6] = 0;
                printf("OEM id: '%s'\n",tmp);

                memcpy(tmp,&sdth.OEM_table_id,8); tmp[8] = 0;
                printf("OEM table id: '%s' rev %u ",tmp,sdth.OEM_revision);

                memcpy(tmp,&sdth.creator_id,4); tmp[4] = 0;
                printf("Creator id: '%s' rev %u",tmp,sdth.creator_revision);

                if (!memcmp(sdth.signature,"MCFG",4)) {
                    struct acpi_mcfg_entry entry;
                    uint64_t o = addr + 44;
                    unsigned int count;

                    printf("\nPCI Express map:");
                    assert(sizeof(struct acpi_mcfg_entry) == 16);
                    count = (unsigned int)(tmplen / sizeof(struct acpi_mcfg_entry));
                    while (count != 0) {
                        acpi_memcpy_from_phys(&entry,o,sizeof(struct acpi_mcfg_entry));
                        o += sizeof(struct acpi_mcfg_entry);

                        /* Some bioses I test against seem to return enough for 3 but fill in only 1? */
                        if (entry.base_address != 0ULL || entry.start_pci_bus_number != 0 || entry.end_pci_bus_number != 0) {
                            uint64_t sz;

                            if (entry.start_pci_bus_number > entry.end_pci_bus_number)
                                entry.start_pci_bus_number = entry.end_pci_bus_number;

                            sz = (((unsigned long long)(entry.end_pci_bus_number - entry.start_pci_bus_number)) + 1ULL) << 20ULL;
                            printf("\n  @0x%08llX-0x%08llX seg=%u bus=%u-%u",
                                (unsigned long long)entry.base_address,
                                (unsigned long long)(entry.base_address + sz - 1ULL),
                                (unsigned int)entry.pci_segment_group_number,
                                (unsigned int)entry.start_pci_bus_number,
                                (unsigned int)entry.end_pci_bus_number);
                        }

                        count--;
                    }
                }
            }
            else {
                printf("'%s' check failed",tmp);
            }
        }
        printf("\n");
    }

    acpi_free();
    return 0;
}