Esempio n. 1
0
/*
 * Func: post_sysinfo_scan_mmu_setup
 * Desc: Once we have scanned coreboot tables, we have complete information
 * about different memory ranges. Thus, we can perform a complete mmu
 * initialization. Also, this takes care of DMA area setup
 */
static void post_sysinfo_scan_mmu_setup(void)
{
	struct memrange *ranges;
	uint64_t nranges;
	struct mmu_ranges mmu_ranges;
	struct mmu_memrange *dma_range;

	/* Get memrange info from lib_sysinfo */
	lib_sysinfo_get_memranges(&ranges, &nranges);

	/* Get memory ranges for mmu init from lib_sysinfo memrange */
	dma_range = mmu_init_ranges_from_sysinfo(ranges, nranges, &mmu_ranges);

	/* Disable mmu */
	mmu_disable();

	/* Init mmu */
	mmu_init(&mmu_ranges);

	/* Enable mmu */
	mmu_enable();

	/* Init dma memory */
	init_dma_memory((void *)dma_range->base, dma_range->size);
}
Esempio n. 2
0
/* CPUClass::reset() */
static void mb_cpu_reset(CPUState *s)
{
    MicroBlazeCPU *cpu = MICROBLAZE_CPU(s);
    MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(cpu);
    CPUMBState *env = &cpu->env;

    mcc->parent_reset(s);

    memset(env, 0, offsetof(CPUMBState, end_reset_fields));
    env->res_addr = RES_ADDR_NONE;

    /* Disable stack protector.  */
    env->shr = ~0;

    env->sregs[SR_PC] = cpu->cfg.base_vectors;

#if defined(CONFIG_USER_ONLY)
    /* start in user mode with interrupts enabled.  */
    env->sregs[SR_MSR] = MSR_EE | MSR_IE | MSR_VM | MSR_UM;
#else
    env->sregs[SR_MSR] = 0;
    mmu_init(&env->mmu);
    env->mmu.c_mmu = 3;
    env->mmu.c_mmu_tlb_access = 3;
    env->mmu.c_mmu_zones = 16;
#endif
}
void test_mmu(){

        volatile unsigned int *memory;
    	DEBUG("MMU tests - writing data to memory\r\n");
        memory = (unsigned int *)0x00100000;
        *memory = 0xdeadbeef;
        DEBUG("0x00100000 = 0x%x \r\n", *memory);

        memory = (unsigned int *)0x00200000;
        *memory = 0xf00dcafe;
        DEBUG("0x00200000 = 0x%x \r\n", *memory);

        /* Write to 32MB */
        memory = (unsigned int *)0x02000000;
        *memory = 0xc0ffee;
        DEBUG("0x02000000 = 0x%x \r\n", *memory);

        mmu_init();
        DEBUG("MMU on - "
        "0x00100000 and 0x00200000 swapped, 0x02000000 unmapped\r\n"
        "Reading data from memory\r\n");

        memory = (unsigned int *)0x00100000;
        DEBUG("0x00100000 = 0x%x \r\n", *memory);

        memory = (unsigned int *)0x00200000;
        DEBUG("0x00200000 = 0x%x \r\n", *memory);

        /* Write to 32MB */
        memory = (unsigned int *)0x02000000;
        DEBUG("0x02000000 = 0x%x \r\n", *memory);
}
Esempio n. 4
0
void setup_mmu(enum dram_state dram)
{
	dcache_mmu_disable();

	/* start with mapping everything as strongly ordered. */
	mmu_config_range(0, 4096, DCACHE_OFF);

	/* Map Device memory. */
	mmu_config_range_kb(RPM_START, RPM_SIZE, DCACHE_OFF);

	mmu_config_range_kb(SRAM_START, SRAM_END - SRAM_START,
		DCACHE_WRITEBACK);

	/* Map DRAM memory */
	setup_dram_mappings(dram);

	mmu_disable_range(DRAM_END, 4096 - DRAM_END);

	/* disable Page 0 for trapping NULL pointer references. */
	mmu_disable_range_kb(0, 1);

	mmu_init();

	dcache_mmu_enable();
}
Esempio n. 5
0
int
mmu_reset (ARMul_State * state)
{
	if (state->mmu_inited)
		mmu_exit (state);
	return mmu_init (state);
}
Esempio n. 6
0
void start_armboot(void)
{
	ENTRY entry = (ENTRY)IMAGE_ENTRY;
	unsigned char *pdst = (unsigned char *)IMAGE_ENTRY;
	unsigned int image_data_len = input_data_end - input_data;

	malloc_start = (char *)(_armboot_start - CONFIG_SYS_MALLOC_LEN);

	uart_early_puts("\r\n\r\nCompressed-boot v1.0.0\r\n");

	/* DDR should larger than 16M */
	mmu_init((MEM_BASE_DDR + 0x4000), MEM_BASE_DDR, 0x1000000);
	dcache_enable(0);

	if (input_data[0] == 0x5D) {
		uart_early_puts("Uncompress");
		decompress(input_data, image_data_len, pdst);
		uart_early_puts("Ok\r\n");
	} else {
		int *s = (int *)input_data;
		int *d = (int *)pdst;
		unsigned int len = ((image_data_len + 3) >> 2);
		while (len--)
			*d++ = *s++;
	}
	dcache_disable();

	entry();
}
Esempio n. 7
0
static void mainboard_enable(device_t dev)
{
	dev->ops->init = &mainboard_init;

	/* set up dcache and MMU */
	/* FIXME: this should happen via resource allocator */
	exynos5250_config_l2_cache();
	mmu_init();
	mmu_config_range(0, DRAM_START, DCACHE_OFF);
	mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
	mmu_config_range(DMA_START >> 20, DMA_SIZE >> 20, DCACHE_OFF);
	mmu_config_range(DRAM_END, 4096 - DRAM_END, DCACHE_OFF);
	dcache_invalidate_all();
	dcache_mmu_enable();

	/* this is going to move, but we must have it now and we're
	 * not sure where */
	exception_init();

	const unsigned epll_hz = 192000000;
	const unsigned sample_rate = 48000;
	const unsigned lr_frame_size = 256;
	clock_epll_set_rate(epll_hz);
	clock_select_i2s_clk_source();
	clock_set_i2s_clk_prescaler(epll_hz, sample_rate * lr_frame_size);

	power_enable_xclkout();
}
Esempio n. 8
0
/* CPUClass::reset() */
static void mb_cpu_reset(CPUState *s)
{
    MicroBlazeCPU *cpu = MICROBLAZE_CPU(s);
    MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(cpu);
    CPUMBState *env = &cpu->env;

    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
        log_cpu_state(env, 0);
    }

    mcc->parent_reset(s);

    memset(env, 0, offsetof(CPUMBState, breakpoints));
    env->res_addr = RES_ADDR_NONE;
    tlb_flush(env, 1);

    /* Disable stack protector.  */
    env->shr = ~0;

    env->pvr.regs[0] = PVR0_PVR_FULL_MASK \
                       | PVR0_USE_BARREL_MASK \
                       | PVR0_USE_DIV_MASK \
                       | PVR0_USE_HW_MUL_MASK \
                       | PVR0_USE_EXC_MASK \
                       | PVR0_USE_ICACHE_MASK \
                       | PVR0_USE_DCACHE_MASK \
                       | PVR0_USE_MMU \
                       | (0xb << 8);
    env->pvr.regs[2] = PVR2_D_OPB_MASK \
                        | PVR2_D_LMB_MASK \
                        | PVR2_I_OPB_MASK \
                        | PVR2_I_LMB_MASK \
                        | PVR2_USE_MSR_INSTR \
                        | PVR2_USE_PCMP_INSTR \
                        | PVR2_USE_BARREL_MASK \
                        | PVR2_USE_DIV_MASK \
                        | PVR2_USE_HW_MUL_MASK \
                        | PVR2_USE_MUL64_MASK \
                        | PVR2_USE_FPU_MASK \
                        | PVR2_USE_FPU2_MASK \
                        | PVR2_FPU_EXC_MASK \
                        | 0;
    env->pvr.regs[10] = 0x0c000000; /* Default to spartan 3a dsp family.  */
    env->pvr.regs[11] = PVR11_USE_MMU | (16 << 17);

#if defined(CONFIG_USER_ONLY)
    /* start in user mode with interrupts enabled.  */
    env->sregs[SR_MSR] = MSR_EE | MSR_IE | MSR_VM | MSR_UM;
    env->pvr.regs[10] = 0x0c000000; /* Spartan 3a dsp.  */
#else
    env->sregs[SR_MSR] = 0;
    mmu_init(&env->mmu);
    env->mmu.c_mmu = 3;
    env->mmu.c_mmu_tlb_access = 3;
    env->mmu.c_mmu_zones = 16;
#endif
}
static void eukrea_cpuimx25_mmu_init(void)
{
	mmu_init();

	arm_create_section(0x80000000, 0x80000000, 128, PMD_SECT_DEF_CACHED);
	arm_create_section(0x90000000, 0x80000000, 128, PMD_SECT_DEF_UNCACHED);

	setup_dma_coherent(0x10000000);

	mmu_enable();
}
Esempio n. 10
0
static void enable_cache(void)
{
	mmu_init();
	/* Whole space is uncached. */
	mmu_config_range(0, 4096, DCACHE_OFF);
	/* SRAM is cached. MMU code will round size up to page size. */
	mmu_config_range((uintptr_t)_sram/MiB, div_round_up(_sram_size, MiB),
			 DCACHE_WRITEBACK);
	mmu_disable_range(0, 1);
	dcache_mmu_enable();
}
Esempio n. 11
0
void sdm845_mmu_init(void)
{
	mmu_init();

	mmu_config_range((void *)(4 * KiB), ((4UL * GiB) - (4 * KiB)), DEV_MEM);
	mmu_config_range((void *)_ssram, REGION_SIZE(ssram), CACHED_RAM);
	mmu_config_range((void *)_bsram, REGION_SIZE(bsram), CACHED_RAM);
	mmu_config_range((void *)_dma_coherent, REGION_SIZE(dma_coherent),
			 UNCACHED_RAM);

	mmu_enable();
}
Esempio n. 12
0
static void nios2_cpu_initfn(Object *obj)
{
    CPUState *cs = CPU(obj);
    Nios2CPU *cpu = NIOS2_CPU(obj);
    CPUNios2State *env = &cpu->env;

    cs->env_ptr = env;

#if !defined(CONFIG_USER_ONLY)
    mmu_init(env);
#endif
}
Esempio n. 13
0
void        init_clay(t_clay *clay, const char *rom_path)
{
    clay->cpu.memRead   = mmu_mem_read;
    clay->cpu.memWrite  = mmu_mem_write;
    clay->cpu.ioRead    = io_handler_read;
    clay->cpu.ioWrite   = io_handler_write;

    mmu_init(&clay->mmu, rom_path);
    z80ctc_init(&clay->ctc);
    ay_3_8912_init(&clay->ay);
   if (audio_output_init(&clay->audio_out, 44100*2, &clay->ay, (audio_output_sample_callback)ay_3_8912_sample_stereo))  // 2 sec sound buffer
       fprintf(stderr, "An error occured while initializing the sound sampler.\n");
}
Esempio n. 14
0
static void __attribute__((noinline)) romstage(void)
{
	timestamp_init(0);
	timestamp_add_now(TS_START_ROMSTAGE);

	console_init();
	exception_init();

	sdram_init(get_sdram_config());

	/* used for MMU and CBMEM setup, in MB */
	u32 dram_start_mb = (uintptr_t)_dram/MiB;
	u32 dram_end_mb = sdram_max_addressable_mb();
	u32 dram_size_mb = dram_end_mb - dram_start_mb;

	configure_l2_cache();
	mmu_init();
	/* Device memory below DRAM is uncached. */
	mmu_config_range(0, dram_start_mb, DCACHE_OFF);
	/* SRAM is cached. MMU code will round size up to page size. */
	mmu_config_range((uintptr_t)_sram/MiB, div_round_up(_sram_size, MiB),
			 DCACHE_WRITEBACK);
	/* DRAM is cached. */
	mmu_config_range(dram_start_mb, dram_size_mb, DCACHE_WRITEBACK);
	/* A window for DMA is uncached. */
	mmu_config_range((uintptr_t)_dma_coherent/MiB,
			 _dma_coherent_size/MiB, DCACHE_OFF);
	/* The space above DRAM is uncached. */
	if (dram_end_mb < 4096)
		mmu_config_range(dram_end_mb, 4096 - dram_end_mb, DCACHE_OFF);
	mmu_disable_range(0, 1);
	dcache_mmu_enable();

	/*
	 * A watchdog reset only resets part of the system so it ends up in
	 * a funny state. If that happens, we need to reset the whole machine.
	 */
	if (power_reset_status() == POWER_RESET_WATCHDOG) {
		printk(BIOS_INFO, "Watchdog reset detected, rebooting.\n");
		hard_reset();
	}

	/* FIXME: this may require coordination with moving timestamps */
	cbmem_initialize_empty();

	early_mainboard_init();

	run_ramstage();
}
Esempio n. 15
0
void bootblock_soc_init(void)
{
	rkclk_init();

	mmu_init();
	/* Start with a clean slate. */
	mmu_config_range(0, 4096, DCACHE_OFF);
	/* SRAM is tightly wedged between registers, need to use subtables. Map
	 * write-through as equivalent for non-cacheable without XN on A17. */
	mmu_config_range_kb((uintptr_t)_sram/KiB,
			    _sram_size/KiB, DCACHE_WRITETHROUGH);
	dcache_mmu_enable();

	rkclk_configure_crypto(148500*KHz);
}
Esempio n. 16
0
int gboot_main()
{

	int num;
#ifdef MMU_ON
    mmu_init();
#endif
	
	led_init();
	key_init();
	int_irq();
	uart_init();
	led_on();
	while(1)
	{
		
		printf("\n\r************************************\n\r");
		printf("\n\r**********kindlyde******************\n\r");
		printf("\n\r1:Downloads Linux Kernel from TFTP Servers\n\r");
		printf("\n\r2:Boot Linux from Ram\n\r");
		printf("\n\r3:Boot Linux from Nand Flash\n\r");
		printf("\n\rplease Select\n\r");
		
		scanf("%d", &num);
		//putc('a');
		switch (num)
		{
			case 1:
			
			break;
			
			case 2:
			
			break;
			
			case 3:
			
			break;
			
			default: 
				printf("\n\rError: please select agian\n\r");
			break;
		}
	
	
	}	
    return 0;    
}
Esempio n. 17
0
int gboot_main()
{
	  int num;
#ifdef MMU_ON
    mmu_init();
#endif
    led_init();
    button_init();
    init_irq();
    
    uart_init();
   
    while(1)
		{
			printf("\n***************************************\n\r");
    	printf("\n*****************GBOOT*****************\n\r");
    	printf("1:Download Linux Kernel from TFTP Server!\n\r");
    	printf("2:Boot Linux from RAM!\n\r");
    	printf("3:Boor Linux from Nand Flash!\n\r");
    	printf("\n Plese Select:");
    	
    	scanf("%d",&num);
    
        switch (num)
        {
            case 1:
            //tftp_load();
            break;
            
            case 2:
            //boot_linux_ram();
            break;
            
            case 3:
            //boot_linux_nand();
            break;
            
            default:
                printf("Error: wrong selection!\n\r");
            break;	
        }
			
			
	  }
    	  	
    
    return 0;    
}
Esempio n. 18
0
void tegra132_mmu_init(void)
{
	uintptr_t tz_base_mib;
	size_t tz_size_mib;
	size_t ttb_size_mib;
	struct memranges *map = &t132_mmap_ranges;

	tegra132_memrange_init(map);
	mainboard_add_memory_ranges(map);
	/* Place page tables at the base of the trust zone region. */
	carveout_range(CARVEOUT_TZ, &tz_base_mib, &tz_size_mib);
	tz_base_mib *= MiB;
	ttb_size_mib = TTB_SIZE * MiB;
	mmu_init(map, (void *)tz_base_mib, ttb_size_mib);
	mmu_enable();
}
Esempio n. 19
0
mmu_t *mmu_create(int nthreads, int hazards_per_thread, int plist_size)
{
	mmu_t *new_mmu = NULL;

	new_mmu = malloc(sizeof(*new_mmu));
	if (new_mmu == NULL)
		return NULL;

	if (mmu_init(new_mmu, nthreads, hazards_per_thread, plist_size) < 0) {
		free(new_mmu);
		return NULL;
	}

	new_mmu->__dynamic = 1;
	return new_mmu;
}
static void eukrea_cpuimx27_mmu_init(void)
{
	mmu_init();

	arm_create_section(0xa0000000, 0xa0000000, 128, PMD_SECT_DEF_CACHED);
	arm_create_section(0xb0000000, 0xa0000000, 128, PMD_SECT_DEF_UNCACHED);

	setup_dma_coherent(0x10000000);

#if TEXT_BASE & (0x100000 - 1)
#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
#else
	arm_create_section(0x0,        TEXT_BASE,   1, PMD_SECT_DEF_UNCACHED);
#endif
	mmu_enable();
}
Esempio n. 21
0
void mt8173_mmu_init(void)
{
	mmu_init();

	/* Set 0x0 to the end of 2GB dram address as device memory */
	mmu_config_range((void *)0, (uintptr_t)_dram + 2U * GiB, DEV_MEM);

	/* SRAM is cached */
	mmu_config_range(_sram_l2c, _sram_l2c_size + _sram_size, CACHED_MEM);

	/* DMA is non-cached and is reserved for TPM & da9212 I2C DMA */
	mmu_config_range(_dma_coherent, _dma_coherent_size, UNCACHED_MEM);

	/* set ttb as secure */
	mmu_config_range(_ttb, _ttb_size, SECURE_MEM);

	mmu_enable();
}
Esempio n. 22
0
void bootblock_soc_init(void)
{
	if (get_wakeup_state() == WAKEUP_DIRECT) {
		wakeup();
		/* Never returns. */
	}

	/* set up dcache and MMU */
	mmu_init();
	mmu_disable_range(0, SRAM_START);
	mmu_config_range(SRAM_START, SRAM_SIZE, DCACHE_WRITEBACK);
	mmu_config_range(SRAM_END, 4096 - SRAM_END, DCACHE_OFF);
	dcache_mmu_enable();

	/* For most ARM systems, we have to initialize firmware media source
	 * (ex, SPI, SD/MMC, or eMMC) now; but for Exynos platform, that is
	 * already handled by iROM so there's no need to setup again.
	 */
}
Esempio n. 23
0
/*
 * All AE210P hardware initialization
 */
void hardware_init(void)
{
	mmu_init();                     /* mmu/cache */
	plf_init();                     /* Perform any platform specific initializations */

#if (defined(CONFIG_CPU_ICACHE_ENABLE) || defined(CONFIG_CPU_DCACHE_ENABLE))
	unsigned int reg;

	/* Invalid ICache */
	nds32_icache_flush();

	/* Invalid DCache */
	nds32_dcache_invalidate();

	/* Enable I/Dcache */
	reg = (__nds32__mfsr(NDS32_SR_CACHE_CTL) & ~CACHE_CTL_MSK) | CACHE_CTL_CACHE_ON;
	__nds32__mtsr(reg, NDS32_SR_CACHE_CTL);
#endif
}
Esempio n. 24
0
//-------------------------------------------------------------------------
// MAIN
//-------------------------------------------------------------------------
int main(void)
{
	oscc_init();							// Oscillator
	PSSR = (PSSR_RDH | PSSR_PH);   			// Reenable the GPIO buffers (needed out of reset)
	//SOS_SET_PIN_DIRECTIONS();				// GPIO
	DVFS_SwitchCoreFreq(104, 104);			// Switch to 104MHz mode
	//DVFS_SwitchCoreFreq(13, 13);			// Switch to 13MHz mode
	memory_init();							// SDRAM
	mmu_init();								// MMU
	//gpio_init();							// GPIO Interrupts
	//wdt_init();							// WATCHDOG
	PXA27XGPIOInt_init();
	pmic_init();
	led_init();								// LEDS
	//systime_init();						// LOCAL TIME
	timer_hardware_init(
		DEFAULT_INTERVAL, DEFAULT_SCALE);	// SYSTEM TIMER
	sos_main(SOS_BOOT_NORMAL);
	return 0;
}
static int eukrea_cpuimx35_mmu_init(void)
{
	mmu_init();

	arm_create_section(0x80000000, 0x80000000, 128, PMD_SECT_DEF_CACHED);
	arm_create_section(0x90000000, 0x80000000, 128, PMD_SECT_DEF_UNCACHED);

	setup_dma_coherent(0x10000000);

#if TEXT_BASE & (0x100000 - 1)
#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
#else
	arm_create_section(0x0,        TEXT_BASE,   1, PMD_SECT_DEF_UNCACHED);
#endif
	mmu_enable();

#ifdef CONFIG_CACHE_L2X0
	l2x0_init((void __iomem *)0x30000000, 0x00030024, 0x00000000);
#endif
	return 0;
}
Esempio n. 26
0
ARM_Interpreter::ARM_Interpreter()  {
    m_state = new ARMul_State;

    ARMul_EmulateInit();
    ARMul_NewState(m_state);

    m_state->abort_model = 0;
    m_state->cpu = (cpu_config_t*)&s_arm11_cpu_info;
    m_state->bigendSig = LOW;

    ARMul_SelectProcessor(m_state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
    m_state->lateabtSig = LOW;
    mmu_init(m_state);

    // Reset the core to initial state
    ARMul_Reset(m_state);
    m_state->NextInstr = 0;
    m_state->Emulate = 3;

    m_state->pc = m_state->Reg[15] = 0x00000000;
    m_state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
}
Esempio n. 27
0
/*
 * Machine-dependent startup code
 */
void
machine_startup(void)
{
	void *vector_offset = 0;

	/*
	 * Reserve system pages.
	 */
	page_reserve(kvtop(SYSPAGE), SYSPAGESZ);

	/*
	 * Copy exception vectors.
	 */
	memcpy(vector_offset, &exception_vector, 0x3000);

#ifdef CONFIG_MMU
	/*
	 * Initialize MMU
	 */
	mmu_init(mmumap_table);
#endif
}
Esempio n. 28
0
static void mainboard_enable(device_t dev)
{
	dev->ops->init = &mainboard_init;

	/* set up dcache and MMU */
	/* FIXME: this should happen via resource allocator */
	exynos5250_config_l2_cache();
	mmu_init();
	mmu_config_range(0, DRAM_START, DCACHE_OFF);
	mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
	mmu_config_range((uintptr_t)_dma_coherent/MiB,
			 _dma_coherent_size/MiB, DCACHE_OFF);
	mmu_config_range(DRAM_END, 4096 - DRAM_END, DCACHE_OFF);
	dcache_mmu_enable();

	const unsigned epll_hz = 192000000;
	const unsigned sample_rate = 48000;
	const unsigned lr_frame_size = 256;
	clock_epll_set_rate(epll_hz);
	clock_select_i2s_clk_source();
	clock_set_i2s_clk_prescaler(epll_hz, sample_rate * lr_frame_size);

	power_enable_xclkout();
}
Esempio n. 29
0
void
pi_start(void)
{
#warning IMPLEMENT _start
	stage2_args args;

	clear_bss();
	call_ctors();

	cpu_init();
	gpio_init();

	// Flick on "OK" led
	GPIO_CLR(16);

	mmu_init();
	serial_init();
	console_init();

	args.heap_size = HEAP_SIZE;
	args.arguments = NULL;

	main(&args);
}
Esempio n. 30
0
extern "C" int
start_gen(int argc, const char **argv, struct image_header *uimage, void *fdt)
{
	stage2_args args;

	clear_bss();
		// call C++ constructors before doing anything else
	call_ctors();
	args.heap_size = HEAP_SIZE;
	args.arguments = NULL;
	args.arguments_count = 0;
	args.platform.boot_tgz_data = NULL;
	args.platform.boot_tgz_size = 0;
	args.platform.fdt_data = NULL;
	args.platform.fdt_size = 0;

	gUImage = uimage;
	gFDT = fdt;	//XXX: make a copy?
		// TODO: check for atags instead and convert them

	if (argv) {
		// skip the kernel name
		++argv;
		--argc;
	}
	// TODO: Ensure cmdline is mapped into memory by MMU before usage.

	// if we get passed a uimage, try to find the third blob
	// only if we do not have FDT data yet
	if (gUImage != NULL
		&& !gFDT
		&& image_multi_getimg(gUImage, 2,
			(uint32*)&args.platform.fdt_data,
			&args.platform.fdt_size)) {
		// found a blob, assume it is FDT data, when working on a platform
		// which does not have an FDT enabled U-Boot
		gFDT = args.platform.fdt_data;
	}

	// We have to cpu_init *before* calling FDT functions
	cpu_init();

	serial_init(gFDT);

	#if defined(__ARM__)
	arch_mailbox_init();
	#endif

	// initialize the OpenFirmware wrapper
	of_init(NULL);

	console_init();

	// if we get passed an FDT, check /chosen for initrd and bootargs
	if (gFDT != NULL) {
		int node = fdt_path_offset(gFDT, "/chosen");
		const void *prop;
		int len;
		phys_addr_t initrd_start = 0, initrd_end = 0;

		if (node >= 0) {
			prop = fdt_getprop(gFDT, node, "linux,initrd-start", &len);
			if (prop && len == 4)
				initrd_start = fdt32_to_cpu(*(uint32_t *)prop);
			prop = fdt_getprop(gFDT, node, "linux,initrd-end", &len);
			if (prop && len == 4)
				initrd_end = fdt32_to_cpu(*(uint32_t *)prop);
			if (initrd_end > initrd_start) {
				args.platform.boot_tgz_data = (void *)initrd_start;
				args.platform.boot_tgz_size = initrd_end - initrd_start;
				dprintf("Found boot tgz from FDT @ %p, %" B_PRIu32 " bytes\n",
					args.platform.boot_tgz_data, args.platform.boot_tgz_size);
			}
			// we check for bootargs after remapping the FDT
		}
	}

	// if we get passed a uimage, try to find the second blob
	if (gUImage != NULL
		&& image_multi_getimg(gUImage, 1,
			(uint32*)&args.platform.boot_tgz_data,
			&args.platform.boot_tgz_size)) {
		dprintf("Found boot tgz from uimage @ %p, %" B_PRIu32 " bytes\n",
			args.platform.boot_tgz_data, args.platform.boot_tgz_size);
	}

	{ //DEBUG:
		int i;
		dprintf("argc = %d\n", argc);
		for (i = 0; i < argc; i++)
			dprintf("argv[%d] @%lx = '%s'\n", i, (uint32)argv[i], argv[i]);
		dprintf("os: %d\n", (int)gUBootOS);
		dprintf("gd @ %p\n", gUBootGlobalData);
		if (gUBootGlobalData) {
			dprintf("gd->bd @ %p\n", gUBootGlobalData->bd);
			dprintf("gd->fb_base @ %p\n", (void*)gUBootGlobalData->fb_base);
		}
		if (gUImage)
			dump_uimage(gUImage);
		if (gFDT)
			dump_fdt(gFDT);
	}
	
	if (args.platform.boot_tgz_size > 0) {
		insert_physical_allocated_range((addr_t)args.platform.boot_tgz_data,
			args.platform.boot_tgz_size);
	}

	// save the size of the FDT so we can map it easily after mmu_init
	size_t fdtSize = gFDT ? fdt_totalsize(gFDT) : 0;
	dprintf("fdtSize: 0x%" B_PRIxSIZE "\n", fdtSize);

	mmu_init();

	// Handle our tarFS post-mmu
	if (args.platform.boot_tgz_size > 0) {
		args.platform.boot_tgz_data = (void*)mmu_map_physical_memory((addr_t)
			args.platform.boot_tgz_data, args.platform.boot_tgz_size,
			kDefaultPageFlags);
	}
	// .. and our FDT
	if (gFDT != NULL)
		gFDT = (void*)mmu_map_physical_memory((addr_t)gFDT, fdtSize, kDefaultPageFlags);

	// if we get passed an FDT, check /chosen for bootargs now
	// to avoid having to copy them.
	if (gFDT != NULL) {
		int node = fdt_path_offset(gFDT, "/chosen");
		const void *prop;
		int len;

		if (node >= 0) {
			prop = fdt_getprop(gFDT, node, "bootargs", &len);
			if (prop) {
				dprintf("Found bootargs: %s\n", (const char *)prop);
				static const char *sArgs[] = { NULL, NULL };
				sArgs[0] = (const char *)prop;
				// override main() args
				args.arguments = sArgs;
				args.arguments_count = 1;
			}
		}
		dprintf("args.arguments_count = %" B_PRId32 "\n", args.arguments_count);
		for (int i = 0; i < args.arguments_count; i++)
			dprintf("args.arguments[%d] @%lx = '%s'\n", i,
				(uint32)args.arguments[i], args.arguments[i]);
	}

	// wait a bit to give the user the opportunity to press a key
//	spin(750000);

	// reading the keyboard doesn't seem to work in graphics mode
	// (maybe a bochs problem)
//	sBootOptions = check_for_boot_keys();
	//if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT)
		serial_enable();

	main(&args);
	return 0;
}