Beispiel #1
0
static int cfe_nvram_chk()
{
	char *name, *value, *end, *eq;
        unsigned int i;
        int ret, name_head, nvram_len;
        unsigned char *ptr;

        if(cfe_buf == NULL||cfe_mtd == NULL)
                if((ret = cfe_init()))
                        return ret;
/*
        printk("cfe_nvram_chk: dump data\n");
        printk("\n####################\n");
        for(i=0, ptr=(unsigned char *)cfe_nvram_header; i< cfe_embedded_size; i++, ptr++)
        {
                if(i%16==0) printk("%04x: %02x ", i, *ptr);
                else if(i%16==15) printk("%02x\n", *ptr);
                else if(i%16==7) printk("%02x - ", *ptr);
                else printk("%02x ", *ptr);
        }
        printk("\n####################\n");
        printk("\ncfe_nvram_chk: cfe_nvram_header(%08x)\n", (unsigned int)cfe_nvram_header);
        printk("cfe_nvram_chk: cfe_nvram_header->len=%d(0x%08x)\n", cfe_nvram_header->len, cfe_nvram_header->len);
*/
	nvram_len = cfe_nvram_header->len;
        name = (char *) &cfe_nvram_header[1];
        end = (char *) cfe_nvram_header + nvram_len - 2;
        end[0] = end[1] = '\0';
	name_head = (int)name;
	i = 0;	
        for (; *name; name = value + strlen(value) + 1) {
//        	printk("%04x: %s\n",i, name);
                if (!(eq = strchr(name, '='))) {
			printk("*** Illegal nvram format at %04x: %s !!!!\n", i, name);
                        return 0;
		}

                *eq = '\0';
                value = eq + 1;
                *eq = '=';

		i += strlen(name)+1;
        }
        if(((int)name - name_head) < 0x0f4b) {
		printk("Unexpect \\0 inside nvram: %04x\n", ((int)name -name_head));
		return 0;
	}

	return 1;
}
Beispiel #2
0
void cfe_update(const char *keyword, const char *value)
{
        unsigned long i, offset;
        struct nvram_header tmp, *header;
        uint8 crc;
//        int ret;
        int found = 0;

        if(!cfe_buf||!cfe_mtd)
                cfe_init();

        if (!cfe_buf||!cfe_mtd) return;

        header = cfe_nvram_header;

        printk("before: %x %x\n", header->len,  cfe_nvram_header->crc_ver_init&0xff); 

        for(i=CFE_NVRAM_START;i<=CFE_NVRAM_END;i++)
        {
                if(strncmp(&cfe_buf[i], keyword, strlen(keyword))==0)
                {
                        printk("before: %s\n", cfe_buf+i); 
                        offset=strlen(keyword);
                        memcpy(cfe_buf+i+offset+1, value, strlen(value));
                        printk("after: %s\n", cfe_buf+i); 
                        found = 1;
                }
        }

        if(!found)
        {
                char *tmp_buf = (char *)cfe_nvram_header;

                /* printk("header len: %x\n", header->len); */
                sprintf(tmp_buf+header->len, "%s=%s", keyword, value);
                header->len = header->len + strlen(keyword) + strlen(value) + 2;
                /* printk("header len: %x\n", header->len); */
        }

        tmp.crc_ver_init = htol32(header->crc_ver_init);
        tmp.config_refresh = htol32(header->config_refresh);
        tmp.config_ncdl = htol32(header->config_ncdl);
        crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE);

        /* Continue CRC8 over data bytes */
        crc = hndcrc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc);
        header->crc_ver_init = (header->crc_ver_init&0xFFFFFF00)|crc;
        printk("after: %x %x\n", header->crc_ver_init&0xFF, crc); 
}
Beispiel #3
0
int
main(long fwhandle,long evector,long fwentry,long fwseal)
{
        struct stat sb;
	const char *reason;
	int fd;

	/* Init prom callback vector. */
	cfe_init(fwhandle,fwentry);
	init_console();

        putstr("\nNetBSD/sbmips " NETBSD_VERS " " BOOTXX_FS_NAME " Primary Bootstrap\n");

        if (!booted_dev_open()) {
		reason = "Can't open boot device.";
                goto fail;
        }

	fd = open("boot", 0);
	if (fd == -1 || (fstat(fd, &sb) == -1)) {
		reason = "Can't open /boot.";
		goto failclose;
	}

	if (sb.st_size > SECONDARY_MAX_LOAD) {
		reason = "/boot too large.";
		goto failclose;
	}

	if (read(fd, (void*)SECONDARY_LOAD_ADDRESS, sb.st_size) != sb.st_size) {
		reason = "/boot load failed.";
		goto failclose;
	}

	cfe_flushcache(0);

	putstr("Jumping to entry point...\n");
	(*((void(*)(long,long,long))SECONDARY_LOAD_ADDRESS))(fwhandle,booted_dev_fd,fwentry);

	reason = "Secondary boot returned!";
failclose:
	booted_dev_close();
fail:
	putstr(reason);
	putstr("\n\nPRIMARY BOOTSTRAP FAILED!\n");

	return 1;
}
Beispiel #4
0
static int cfe_dump(void)
{
        unsigned int i;
        int ret;
        unsigned char *ptr;

        if(cfe_buf == NULL||cfe_mtd == NULL)
                if((ret = cfe_init()))
                        return ret;

        printk("cfe_dump: cfe_buf(%08x), dump 1024 byte\n", (unsigned int)cfe_buf);
        for(i=0, ptr=(unsigned char *)cfe_nvram_header - 1024; ptr < (unsigned char *)cfe_nvram_header; i++, ptr++)
        {
                if(i%16==0) printk("%04x: %02x ", i, *ptr);
                else if(i%16==15) printk("%02x\n", *ptr);
                else if(i%16==7) printk("%02x - ", *ptr);
                else printk("%02x ", *ptr);
        }

        printk("\ncfe_dump: cfe_nvram_header(%08x)\n", (unsigned int)cfe_nvram_header);
        printk("cfe_dump: cfe_nvram_header->len(0x%08x)\n", cfe_nvram_header->len);

        printk("\n####################\n");
        for(i=0, ptr=(unsigned char *)cfe_nvram_header; i< cfe_embedded_size; i++, ptr++)
        {
                if(i%16==0) printk("%04x: %02x ", i, *ptr);
                else if(i%16==15) printk("%02x\n", *ptr);
                else if(i%16==7) printk("%02x - ", *ptr);
                else printk("%02x ", *ptr);
        }
        printk("\n####################\n");
        ptr = (unsigned char *)&cfe_nvram_header[1];
        while(*ptr)
        {
                printk("%s\n", ptr);
                ptr += strlen(ptr) + 1;
        }
        printk("\n####################\n");
        for(i=0, ptr=((unsigned char *)cfe_nvram_header) + cfe_embedded_size; i<16; i++, ptr++)
        {
                if(i%16==0) printk("%04x: %02x ", i, *ptr);
                else if(i%16==15) printk("%02x\n", *ptr);
                else if(i%16==7) printk("%02x - ", *ptr);
                else printk("%02x ", *ptr);
        }
        return 0;
}
Beispiel #5
0
void
platform_start(__register_t a0, __register_t a1, __register_t a2,
	       __register_t a3)
{
	vm_offset_t 		 kernend;
	uint64_t		 platform_counter_freq;
	int			 error;

	/* clear the BSS and SBSS segments */
	kernend = (vm_offset_t)&end;
	memset(&edata, 0, kernend - (vm_offset_t)(&edata));

	mips_postboot_fixup();

	/* Initialize pcpu stuff */
	mips_pcpu0_init();

#ifdef CFE
	/*
	 * Initialize CFE firmware trampolines. This must be done
	 * before any CFE APIs are called, including writing
	 * to the CFE console.
	 *
	 * CFE passes the following values in registers:
	 * a0: firmware handle
	 * a2: firmware entry point
	 * a3: entry point seal
	 */
	if (a3 == CFE_EPTSEAL)
		cfe_init(a0, a2);
#endif

	/* Init BCM platform data */
	if ((error = bcm_init_platform_data(&bcm_platform_data)))
		panic("bcm_init_platform_data() failed: %d", error);

	platform_counter_freq = bcm_get_cpufreq(bcm_get_platform());

	/* CP0 ticks every two cycles */
	mips_timer_early_init(platform_counter_freq / 2);

	cninit();

	mips_init();

	mips_timer_init_params(platform_counter_freq, 1);
}
Beispiel #6
0
static __init void prom_init_cfe(void)
{
	uint32_t cfe_ept;
	uint32_t cfe_handle;
	uint32_t cfe_eptseal;
	int argc = fw_arg0;
	char **envp = (char **) fw_arg2;
	int *prom_vec = (int *) fw_arg3;

	/*
	 * Check if a loader was used; if NOT, the 4 arguments are
	 * what CFE gives us (handle, 0, EPT and EPTSEAL)
	 */
	if (argc < 0) {
		cfe_handle = (uint32_t)argc;
		cfe_ept = (uint32_t)envp;
		cfe_eptseal = (uint32_t)prom_vec;
	} else {
		if ((int)prom_vec < 0) {
			/*
			 * Old loader; all it gives us is the handle,
			 * so use the "known" entrypoint and assume
			 * the seal.
			 */
			cfe_handle = (uint32_t)prom_vec;
			cfe_ept = 0xBFC00500;
			cfe_eptseal = CFE_EPTSEAL;
		} else {
			/*
			 * Newer loaders bundle the handle/ept/eptseal
			 * Note: prom_vec is in the loader's useg
			 * which is still alive in the TLB.
			 */
			cfe_handle = prom_vec[0];
			cfe_ept = prom_vec[2];
			cfe_eptseal = prom_vec[3];
		}
	}

	if (cfe_eptseal != CFE_EPTSEAL) {
		/* too early for panic to do any good */
		printk(KERN_ERR "CFE's entrypoint seal doesn't match.");
		while (1) ;
	}

	cfe_init(cfe_handle, cfe_ept);
}
Beispiel #7
0
void
platform_start(__register_t a0, __register_t a1, __register_t a2,
               __register_t a3)
{
    vm_offset_t 		 kernend;
    uint64_t		 platform_counter_freq;
    struct bcm_socinfo	*socinfo;

    /* clear the BSS and SBSS segments */
    kernend = (vm_offset_t)&end;
    memset(&edata, 0, kernend - (vm_offset_t)(&edata));

    mips_postboot_fixup();

    /* Initialize pcpu stuff */
    mips_pcpu0_init();

    socinfo = bcm_get_socinfo();
    platform_counter_freq = socinfo->cpurate * 1000 * 1000; /* BCM4718 is 480MHz */

    mips_timer_early_init(platform_counter_freq);

#ifdef CFE
    /*
     * Initialize CFE firmware trampolines before
     * we initialize the low-level console.
     *
     * CFE passes the following values in registers:
     * a0: firmware handle
     * a2: firmware entry point
     * a3: entry point seal
     */
    if (a3 == CFE_EPTSEAL)
        cfe_init(a0, a2);
#endif
    cninit();

    mips_init();

    /* BCM471x timer is 1/2 of Clk */
    mips_timer_init_params(platform_counter_freq, 1);
}
Beispiel #8
0
void
platform_start(__register_t a0, __register_t a1, __register_t a2,
               __register_t a3)
{
    /*
     * Make sure that kseg0 is mapped cacheable-coherent
     */
    kseg0_map_coherent();

    /* clear the BSS and SBSS segments */
    memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata);
    mips_postboot_fixup();

    sb_intr_init(0);
    sb_timecounter_init();

    /* Initialize pcpu stuff */
    mips_pcpu0_init();

#ifdef CFE
    /*
     * Initialize CFE firmware trampolines before
     * we initialize the low-level console.
     *
     * CFE passes the following values in registers:
     * a0: firmware handle
     * a2: firmware entry point
     * a3: entry point seal
     */
    if (a3 == CFE_EPTSEAL)
        cfe_init(a0, a2);
#endif
    cninit();

    mips_init();

    mips_timer_init_params(sb_cpu_speed(), 0);
}
Beispiel #9
0
void
prom_init(void)
{
	uint32_t cfe_ept, cfe_handle;
	unsigned int cfe_eptseal;
	int argc = fw_arg0;
	char **envp = (char **) fw_arg2;
	int *prom_vec = (int *) fw_arg3;
	
	/*
	 * Check if a loader was used; if NOT, the 4 arguments are
	 * what CFE gives us (handle, 0, EPT and EPTSEAL)
	 */
        cfe_handle = (uint32_t)(long)argc;
	cfe_ept = (long)envp;
	cfe_eptseal = (uint32_t)(unsigned long)prom_vec;

	if (cfe_eptseal != CFE_EPTSEAL) {
		/* too early for panic to do any good */
		return;
	}
	cfe_init(cfe_handle, cfe_ept);
}
Beispiel #10
0
static int cfe_update(const char *keyword, const char *value)
{
        struct nvram_header *header;
        uint8 crc;
        int ret;
        int found = 0;
        char *str, *end, *mv_target = NULL, *mv_start = NULL;

        if(keyword == NULL || *keyword == 0)
                return 0;

        if(cfe_buf == NULL||cfe_mtd == NULL)
                if((ret = cfe_init()))
                        return ret;

        header = cfe_nvram_header;

	printk("cfe_update: before %x %x\n", header->len,  cfe_nvram_header->crc_ver_init&0xff);
        str = (char *) &header[1];
        end = (char *) header + cfe_embedded_size - 2;
        end[0] = end[1] = '\0';

        for (; *str; str += strlen(str) + 1)
        {
                if(!found)
                {
                        if(strncmp(str, keyword, strlen(keyword)) == 0 && str[strlen(keyword)] == '=')
                        {
                                printk("cfe_update: !!!! found !!!!\n");
                                found = 1;
                                if(value != NULL && strlen(str) == strlen(keyword) + 1 + strlen(value))
                                {//string length is the same
                                        strcpy(str+strlen(keyword)+1, value);
                                }
                                else
                                {
                                        mv_target = str;
                                        mv_start = str + strlen(str) + 1;
                                }
                        }
                }
        }
        /* str point to the end of all embedded nvram settings */

        if(mv_target != NULL)
        { /* need to move string */
                int str_len = strlen(mv_target);
                //printk("cfe_update: mv_target(%08x) mv_start(%08x) str(%08x) str_len(%d)\n", (unsigned int)mv_target, (unsigned int)mv_start, (unsigned int)str, str_len);
                if(value != NULL && (str + strlen(keyword) + 1 + strlen(value) + 1 - (str_len + 1)) > end)
                        return -ENOSPC;
                memmove(mv_target, mv_start, str - mv_start);
                //printk("cfe_update: memmove done\n");
                str -= (str_len + 1); /* /set str to the end for placing incoming keyword and value there */
        }

        if(value == NULL)
        {
                //printk("cfe_update: do unset\n");
        }
        else if(!found || mv_target != NULL) /*new or movement */
        { /* append the keyword and value here */
                //printk("cfe_update: str(%08x)\n", (unsigned int) str);
                if((str + strlen(keyword) + 1 + strlen(value) + 1) > end)
                        return -ENOSPC;
                str += sprintf(str, "%s=%s", keyword, value) + 1;
                //printk("cfe_update: append string\n");
        }
/* calc length */
        memset(str, 0, cfe_embedded_size+(char *)header - str);
        str += 2;
        header->len = ROUNDUP(str - (char *) header, 4);
        //printk("cfe_update: header len: %x\n", header->len);
/*/calc crc */
        crc = nvram_calc_crc(header);
        //printk("cfe_update: nvram_calc_crc(header) = 0x%02x\n", crc);
        header->crc_ver_init = (header->crc_ver_init & NVRAM_CRC_VER_MASK)|crc;
        //printk("cfe_update: after %x %x\n", header->crc_ver_init&0xFF, crc);
 
        return 0;
}
Beispiel #11
0
/*
 * Do all the stuff that locore normally does before calling main().
 */
void
mach_init(long fwhandle, long magic, long bootdata, long reserved)
{
	void *kernend, *p0;
	u_long first, last;
	extern char edata[], end[];
	int i;
	uint32_t config;

	/* XXX this code must run on the target CPU */
	config = mips3_cp0_config_read();
	config &= ~MIPS3_CONFIG_K0_MASK;
	config |= 0x05;				/* XXX.  cacheable coherent */
	mips3_cp0_config_write(config);

	/* Zero BSS.  XXXCGD: uh, is this really necessary still?  */
	memset(edata, 0, end - edata);

	/*
	 * Copy the bootinfo structure from the boot loader.
	 * this has to be done before mips_vector_init is
	 * called because we may need CFE's TLB handler
	 */

	if (magic == BOOTINFO_MAGIC)
		memcpy(&bootinfo, (struct bootinfo_v1 *)bootdata,
		    sizeof bootinfo);
	else if (reserved == CFE_EPTSEAL) {
		magic = BOOTINFO_MAGIC;
		bzero(&bootinfo, sizeof bootinfo);
		bootinfo.version = BOOTINFO_VERSION;
		bootinfo.fwhandle = fwhandle;
		bootinfo.fwentry = bootdata;
		bootinfo.ssym = (vaddr_t)end;
		bootinfo.esym = (vaddr_t)end;
	}

	kernend = (void *)mips_round_page(end);
#if NKSYMS || defined(DDB) || defined(LKM)
	if (magic == BOOTINFO_MAGIC) {
		ksym_start = (void *)bootinfo.ssym;
		ksym_end   = (void *)bootinfo.esym;
		kernend = (void *)mips_round_page((vaddr_t)ksym_end);
	}
#endif

	consinit();

	uvm_setpagesize();

	/*
	 * Copy exception-dispatch code down to exception vector.
	 * Initialize locore-function vector.
	 * Clear out the I and D caches.
	 */
	mips_vector_init();

#ifdef DEBUG
	printf("fwhandle=%08X magic=%08X bootdata=%08X reserved=%08X\n",
	    (u_int)fwhandle, (u_int)magic, (u_int)bootdata, (u_int)reserved);
#endif

	strcpy(cpu_model, "sb1250");

	if (magic == BOOTINFO_MAGIC) {
		int idx;
		int added;
		uint64_t start, len, type;

		cfe_init(bootinfo.fwhandle, bootinfo.fwentry);
		cfe_present = 1;

		idx = 0;
		physmem = 0;
		mem_cluster_cnt = 0;
		while (cfe_enummem(idx, 0, &start, &len, &type) == 0) {
			added = 0;
			printf("Memory Block #%d start %08"PRIx64"X len %08"PRIx64"X: %s: ",
			    idx, start, len, (type == CFE_MI_AVAILABLE) ?
			    "Available" : "Reserved");
			if ((type == CFE_MI_AVAILABLE) &&
			    (mem_cluster_cnt < VM_PHYSSEG_MAX)) {
				/*
				 * XXX Ignore memory above 256MB for now, it
				 * XXX needs special handling.
				 */
				if (start < (256*1024*1024)) {
				    physmem += btoc(((int) len));
				    mem_clusters[mem_cluster_cnt].start =
					(long) start;
				    mem_clusters[mem_cluster_cnt].size =
					(long) len;
				    mem_cluster_cnt++;
				    added = 1;
				}
			}
			if (added)
				printf("added to map\n");
			else
				printf("not added to map\n");
			idx++;
		}

	} else {
		/*
		 * Handle the case of not being called from the firmware.
		 */
		/* XXX hardwire to 32MB; should be kernel config option */
		physmem = 32 * 1024 * 1024 / 4096;
		mem_clusters[0].start = 0;
		mem_clusters[0].size = ctob(physmem);
		mem_cluster_cnt = 1;
	}


	for (i = 0; i < sizeof(bootinfo.boot_flags); i++) {
		switch (bootinfo.boot_flags[i]) {
		case '\0':
			break;
		case ' ':
			continue;
		case '-':
			while (bootinfo.boot_flags[i] != ' ' &&
			    bootinfo.boot_flags[i] != '\0') {
				switch (bootinfo.boot_flags[i]) {
				case 'a':
					boothowto |= RB_ASKNAME;
					break;
				case 'd':
					boothowto |= RB_KDB;
					break;
				case 's':
					boothowto |= RB_SINGLE;
					break;
				}
				i++;
			}
		}
	}

	/*
	 * Load the rest of the available pages into the VM system.
	 * The first chunk is tricky because we have to avoid the
	 * kernel, but the rest are easy.
	 */
	first = round_page(MIPS_KSEG0_TO_PHYS(kernend));
	last = mem_clusters[0].start + mem_clusters[0].size;
	uvm_page_physload(atop(first), atop(last), atop(first), atop(last),
		VM_FREELIST_DEFAULT);

	for (i = 1; i < mem_cluster_cnt; i++) {
		first = round_page(mem_clusters[i].start);
		last = mem_clusters[i].start + mem_clusters[i].size;
		uvm_page_physload(atop(first), atop(last), atop(first),
		    atop(last), VM_FREELIST_DEFAULT);
	}

	/*
	 * Initialize error message buffer (at end of core).
	 */
	mips_init_msgbuf();

	/*
	 * Allocate space for proc0's USPACE
	 */
	p0 = (void *)pmap_steal_memory(USPACE, NULL, NULL);
	lwp0.l_addr = proc0paddr = (struct user *)p0;
	lwp0.l_md.md_regs = (struct frame *)((char *)p0 + USPACE) - 1;
	proc0paddr->u_pcb.pcb_context[11] =
	    MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */

	pmap_bootstrap();

	/*
	 * Initialize debuggers, and break into them, if appropriate.
	 */
#if NKSYMS || defined(DDB) || defined(LKM)
	ksyms_init(((uintptr_t)ksym_end - (uintptr_t)ksym_start),
	    ksym_start, ksym_end);
#endif

	if (boothowto & RB_KDB) {
#if defined(DDB)
		Debugger();
#endif
	}
}
Beispiel #12
0
/*
 * prom_init is called just after the cpu type is determined, from setup_arch()
 */
void __init prom_init(void)
{
	uint64_t cfe_ept, cfe_handle;
	unsigned int cfe_eptseal;
	int argc = fw_arg0;
	char **envp = (char **) fw_arg2;
	int *prom_vec = (int *) fw_arg3;

	_machine_restart   = cfe_linux_restart;
	_machine_halt      = cfe_linux_halt;
	_machine_power_off = cfe_linux_halt;

	/*
	 * Check if a loader was used; if NOT, the 4 arguments are
	 * what CFE gives us (handle, 0, EPT and EPTSEAL)
	 */
	if (argc < 0) {
		cfe_handle = (uint64_t)(long)argc;
		cfe_ept = (long)envp;
		cfe_eptseal = (uint32_t)(unsigned long)prom_vec;
	} else {
		if ((int32_t)(long)prom_vec < 0) {
			/*
			 * Old loader; all it gives us is the handle,
			 * so use the "known" entrypoint and assume
			 * the seal.
			 */
			cfe_handle = (uint64_t)(long)prom_vec;
			cfe_ept = (uint64_t)((int32_t)0x9fc00500);
			cfe_eptseal = CFE_EPTSEAL;
		} else {
			/*
			 * Newer loaders bundle the handle/ept/eptseal
			 * Note: prom_vec is in the loader's useg
			 * which is still alive in the TLB.
			 */
			cfe_handle = (uint64_t)((int32_t *)prom_vec)[0];
			cfe_ept = (uint64_t)((int32_t *)prom_vec)[2];
			cfe_eptseal = (unsigned int)((uint32_t *)prom_vec)[3];
		}
	}
	if (cfe_eptseal != CFE_EPTSEAL) {
		/* too early for panic to do any good */
		prom_printf("CFE's entrypoint seal doesn't match. Spinning.");
		while (1) ;
	}
	cfe_init(cfe_handle, cfe_ept);
	/* 
	 * Get the handle for (at least) prom_putchar, possibly for
	 * boot console
	 */
	cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
	if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) {
		if (argc < 0) {
			/*
			 * It's OK for direct boot to not provide a
			 *  command line
			 */
			strcpy(arcs_cmdline, "root=/dev/ram0 ");
#ifdef CONFIG_SIBYTE_PTSWARM
			strcat(arcs_cmdline, "console=ttyS0,115200 ");
#endif
		} else {
			/* The loader should have set the command line */
			/* too early for panic to do any good */
			prom_printf("LINUX_CMDLINE not defined in cfe.");
			while (1) ;
		}
	}

#ifdef CONFIG_BLK_DEV_INITRD
	{
		char *ptr;
		/* Need to find out early whether we've got an initrd.  So scan
		   the list looking now */
		for (ptr = arcs_cmdline; *ptr; ptr++) {
			while (*ptr == ' ') {
				ptr++;
			}
			if (!strncmp(ptr, "initrd=", 7)) {
				initrd_setup(ptr+7);
				break;
			} else {
				while (*ptr && (*ptr != ' ')) {
					ptr++;
				}
			}
		}
	}
#endif /* CONFIG_BLK_DEV_INITRD */

	/* Not sure this is needed, but it's the safe way. */
	arcs_cmdline[CL_SIZE-1] = 0;

	mips_machgroup = MACH_GROUP_SIBYTE;
	prom_meminit();
}
Beispiel #13
0
extern "C" void
start(uint64 cfeHandle, uint64 cfeEntry)
{
	char bootargs[512];

	// stage2 args - might be set via the command line one day
	stage2_args args;
	args.heap_size = HEAP_SIZE;
	args.arguments = NULL;

	cfe_init(cfeHandle, cfeEntry);

	// check for arguments
#if 0//OF
	if (of_getprop(gChosen, "bootargs", bootargs, sizeof(bootargs))
			!= OF_FAILED) {
		static const char *sArgs[] = { NULL, NULL };
		sArgs[0] = (const char *)bootargs;
		args.arguments = sArgs;
		args.arguments_count = 1;
	}
#endif

#if 0//OF
	determine_machine();
#endif
	console_init();

	// XXX:FIXME: doesn't even land here.
	dprintf("testing...\n");
	while (true);

#if 0//OF
	if ((gMachine & MACHINE_QEMU) != 0)
		dprintf("OpenBIOS (QEMU?) OpenFirmware machine detected\n");
	else if ((gMachine & MACHINE_PEGASOS) != 0)
		dprintf("Pegasos PowerPC machine detected\n");
	else
		dprintf("Apple PowerPC machine assumed\n");
#endif

	// Initialize and take over MMU and set the OpenFirmware callbacks - it
	// will ask us for memory after that instead of maintaining it itself
	// (the kernel will need to adjust the callback later on as well)
	arch_mmu_init();

	if (boot_arch_cpu_init() != B_OK)
		cfe_exit(CFE_FLG_WARMSTART, 1);

#if 0//OF FIXME
	if (init_real_time_clock() != B_OK)
		cfe_exit(CFE_FLG_WARMSTART, 1);
#endif

	// check for key presses once
	sBootOptions = 0;
	int key = console_check_for_key();
	if (key == 32) {
		// space bar: option menu
		sBootOptions |= BOOT_OPTION_MENU;
	} else if (key == 27) {
		// ESC: debug output
		sBootOptions |= BOOT_OPTION_DEBUG_OUTPUT;
	}

	gKernelArgs.platform_args.cfe_entry = cfeEntry;

	main(&args);
		// if everything goes fine, main() never returns

	cfe_exit(CFE_FLG_WARMSTART, 1);
}
Beispiel #14
0
/* Initialize hardware.  Called from crt0.  */
void
hardware_init_hook(void)
{
  cfe_init (__cfe_handle, __cfe_entrypt);
  cfe_conshandle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
}
Beispiel #15
0
int cfe_commit(void)
{
        DECLARE_WAITQUEUE(wait, current);
        wait_queue_head_t wait_q;
        struct erase_info erase;
//        unsigned int i;
        int ret;
        size_t erasesize, len;
        u_int32_t offset;
//        char *buf;

        if(!cfe_buf||!cfe_mtd) cfe_init();

        if(!cfe_mtd||!cfe_buf)
        {
                ret = - ENOMEM;
                goto done;
        }

        /* Backup sector blocks to be erased */
        erasesize = ROUNDUP(CFE_NVRAM_SPACE, cfe_mtd->erasesize);

	down(&nvram_sem);

        /* Erase sector blocks */
        init_waitqueue_head(&wait_q);


        for (offset=CFE_NVRAM_START;offset <= CFE_NVRAM_END;offset += cfe_mtd->erasesize) {
           erase.mtd = cfe_mtd;
           erase.addr = offset;
           erase.len = cfe_mtd->erasesize;
           erase.callback = erase_callback;
           erase.priv = (u_long) &wait_q;

           set_current_state(TASK_INTERRUPTIBLE);
           add_wait_queue(&wait_q, &wait);
           /* Unlock sector blocks */
           if (cfe_mtd->unlock)
                   cfe_mtd->unlock(cfe_mtd, offset, cfe_mtd->erasesize);

           if ((ret = cfe_mtd->erase(cfe_mtd, &erase))) {
                set_current_state(TASK_RUNNING);
                remove_wait_queue(&wait_q, &wait);
                printk("cfe_commit: erase error\n");
                goto done;
           }

           /* Wait for erase to finish */
           schedule();
           remove_wait_queue(&wait_q, &wait);
        }

        ret = cfe_mtd->write(cfe_mtd, CFE_NVRAM_START, erasesize, &len, cfe_buf);
        /* printk("Write offset: %x %x %x\n", ret, len, erasesize); */

        if (ret || len != erasesize) {
           printk("cfe_commit: write error\n");
           ret = -EIO;
        }

done:
	up(&nvram_sem);
        if (cfe_mtd)
        {
                put_mtd_device(cfe_mtd);
                cfe_mtd=NULL;
        }
        if(cfe_buf)
        {
                kfree(cfe_buf);
                cfe_buf=NULL;
        }
        /* printk("commit: %d\n", ret); */
        return ret;

}
Beispiel #16
0
/*
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Ralph Campbell.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)boot.c	8.1 (Berkeley) 6/10/93
 */

#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
#include <lib/libsa/loadfile.h>

#include <sys/param.h>
#include <sys/exec.h>
#include <sys/exec_ecoff.h>

#include "stand/common/common.h"
#include "stand/common/cfe_api.h"

#include <machine/autoconf.h>

#if !defined(UNIFIED_BOOTBLOCK) && !defined(SECONDARY_BOOTBLOCK)
#error not UNIFIED_BOOTBLOCK and not SECONDARY_BOOTBLOCK
#endif

char boot_file[128];
char boot_flags[128];
extern int debug;

struct bootinfo_v1 bootinfo;

paddr_t ffp_save, ptbr_save;

int debug;

char *kernelnames[] = {
	"netbsd",		"netbsd.gz",
	"netbsd.bak",		"netbsd.bak.gz",
	"netbsd.old",		"netbsd.old.gz",
	"onetbsd",		"onetbsd.gz",
	"netbsd.mips",		"netbsd.mips.gz",
	NULL
};

int
#if defined(UNIFIED_BOOTBLOCK)
main(long fwhandle,long evector,long fwentry,long fwseal)
#else /* defined(SECONDARY_BOOTBLOCK) */
main(long fwhandle,long fd,long fwentry)
#endif
{
	char *name, **namep;
	u_long marks[MARK_MAX];
	u_int32_t entry;
	int win;

	/* Init prom callback vector. */
	cfe_init(fwhandle,fwentry);

	/* Init the console device */
	init_console();

	/* print a banner */
	printf("\n");
	printf("NetBSD/sbmips " NETBSD_VERS " " BOOT_TYPE_NAME " Bootstrap, Revision %s\n",
	    bootprog_rev);
	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
	printf("\n");

	/* set up the booted device descriptor */
#if defined(UNIFIED_BOOTBLOCK)
        if (!booted_dev_open()) {
                printf("Boot device (%s) open failed.\n",
		    booted_dev_name[0] ? booted_dev_name : "unknown");
                goto fail;
        }
#else /* defined(SECONDARY_BOOTBLOCK) */
	booted_dev_setfd(fd);
#endif

	printf("\n");

	boot_file[0] = 0;
	cfe_getenv("KERNEL_FILE",boot_file,sizeof(boot_file));

	boot_flags[0] = 0;
	cfe_getenv("BOOT_FLAGS",boot_flags,sizeof(boot_flags));

	if (boot_file[0] != 0)
		(void)printf("Boot file: %s\n", boot_file);
	(void)printf("Boot flags: %s\n", boot_flags);

	if (strchr(boot_flags, 'i') || strchr(boot_flags, 'I')) {
		printf("Boot file: ");
		gets(boot_file);
	}

	memset(marks, 0, sizeof marks);
	if (boot_file[0] != '\0')
		win = loadfile(name = boot_file, marks, LOAD_KERNEL) == 0;
	else
		for (namep = kernelnames, win = 0; *namep != NULL && !win;
		    namep++)
			win = loadfile(name = *namep, marks, LOAD_KERNEL) == 0;

	entry = marks[MARK_ENTRY];
	booted_dev_close();
	printf("\n");
	if (!win)
		goto fail;

	(void)printf("Entering %s at 0x%lx...\n", name, (long)entry);

	cfe_flushcache(0);

	bzero(&bootinfo,sizeof(bootinfo));
	bootinfo.version = BOOTINFO_VERSION;
	bootinfo.reserved = 0;
	bootinfo.ssym = marks[MARK_SYM];
	bootinfo.esym = marks[MARK_END];
	strncpy(bootinfo.boot_flags,boot_flags,sizeof(bootinfo.boot_flags));
	strncpy(bootinfo.booted_kernel,name,sizeof(bootinfo.booted_kernel));
	bootinfo.fwhandle = fwhandle;
	bootinfo.fwentry = fwentry;

	(*(void (*)(long,long,long,long))entry)(fwhandle,
						BOOTINFO_MAGIC,
						(long)&bootinfo,
						fwentry);

	(void)printf("KERNEL RETURNED!\n");

fail:
	(void)printf("Boot failed!  Halting...\n");
	halt();
	return 1;
}
Beispiel #17
0
void __init prom_init(void)
{
	char *ptr;

	cfe_init(cfe_handle, cfe_entry);

	bchip_check_compat();
	board_pinmux_setup();

	bchip_mips_setup();
	set_board_nmi_handler();

	/* default to SATA (where available) or MTD rootfs */
#ifdef CONFIG_BRCM_HAS_SATA
	ROOT_DEV = Root_SDA1;
#else
	ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 0);
#endif
	root_mountflags &= ~MS_RDONLY;

	bchip_set_features();

#if defined(CONFIG_BRCM_IKOS_DEBUG)
	strcpy(arcs_cmdline, "debug initcall_debug");
#elif !defined(CONFIG_BRCM_IKOS)
	cfe_read_configuration();
#endif
	brcm_setup_early_printk();

#ifdef CONFIG_CMDLINE_BOOL
#ifdef CONFIG_CMDLINE_OVERRIDE
	strlcpy(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE);
#else
	if (builtin_cmdline[0]) {
		strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
		strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE);
	}
#endif
#endif
	/* provide "ubiroot" alias to reduce typing */
	if (strstr(arcs_cmdline, "ubiroot"))
		strcat(arcs_cmdline, " ubi.mtd=rootfs rootfstype=ubifs "
			"root=ubi0:rootfs");

	ptr = strstr(arcs_cmdline, "memc1=");
	if (ptr)
		brcm_dram1_linux_mb = memparse(ptr + 6, &ptr) >> 20;

	printk(KERN_INFO "Options: enet_en=%d enet0_mii=%d enet_no_mdio=%d "
		"enet1_en=%d moca=%d\n",
		brcm_enet_enabled, brcm_enet0_force_ext_mii,
		brcm_enet_no_mdio, brcm_enet1_enabled, brcm_moca_enabled);
	printk(KERN_INFO "         sata=%d docsis=%d pci=%d pcie=%d smp=%d "
		"usb=%d\n",
		brcm_sata_enabled, brcm_docsis_platform, brcm_pci_enabled,
		brcm_pcie_enabled, brcm_smp_enabled, brcm_usb_enabled);

	bchip_early_setup();

	board_get_ram_size(&brcm_dram0_size_mb, &brcm_dram1_size_mb);

	do {
		unsigned long dram0_mb = brcm_dram0_size_mb, mb;

		mb = min(dram0_mb, BRCM_MAX_LOWER_MB);
		dram0_mb -= mb;

		add_memory_region(0, mb << 20, BOOT_MEM_RAM);
		if (!dram0_mb)
			break;

#ifdef CONFIG_BRCM_UPPER_MEMORY
		mb = min(dram0_mb, BRCM_MAX_UPPER_MB);
		dram0_mb -= mb;

		brcm_upper_tlb_setup();
		add_memory_region(UPPERMEM_START, mb << 20, BOOT_MEM_RAM);
		if (!dram0_mb)
			break;
#endif

#if defined(CONFIG_HIGHMEM)
		add_memory_region(HIGHMEM_START, dram0_mb << 20, BOOT_MEM_RAM);
		break;
#endif
		/*
		 * We wound up here because the chip's architecture cannot
		 * make use of all MEMC0 RAM in Linux.  i.e. no suitable
		 * HIGHMEM or upper memory options are supported by the CPU.
		 *
		 * But we can still report the excess memory as a "bonus"
		 * reserved (bmem) region, so the application can manage it.
		 */
		mb = brcm_dram0_size_mb - dram0_mb;	/* Linux memory */
		if (!brcm_dram1_size_mb && mb == 256) {
			printk(KERN_INFO "MEMC0 split: %lu MB -> Linux; "
				"%lu MB -> extra bmem\n", mb, dram0_mb);
			brcm_dram1_size_mb = dram0_mb;
			brcm_dram1_start = UPPERMEM_START;
		}
	} while (0);

#if defined(CONFIG_HIGHMEM) && defined(CONFIG_BRCM_HAS_1GB_MEMC1)
	if (brcm_dram1_linux_mb > brcm_dram1_size_mb) {
		printk(KERN_WARNING "warning: 'memc1=%luM' exceeds "
			"available memory (%lu MB); ignoring\n",
			brcm_dram1_linux_mb, brcm_dram1_size_mb);
		brcm_dram1_linux_mb = 0;
	} else if (brcm_dram1_linux_mb) {
		/* Since the bootloader can only map the first 256M of memc1
		 * when it boots, if we get memc1= request from bootloader, we
		 * should try to pull the memory from the end to avoid crossing
		 * over the memory that is allocated for boot logo image by
		 * bootloader.
		 */
		unsigned long start_mb, start_b, size, splash_bound = 0;
		if (0 == parse_splash_mem(arcs_cmdline, &splash_bound, &size)) {
			splash_bound += size;
		}

		start_mb = brcm_dram1_size_mb - brcm_dram1_linux_mb;
		start_b  = start_mb << 20;
		if (splash_bound > start_b) {
			unsigned long orig_dram1 = brcm_dram1_linux_mb;
			start_mb = (splash_bound + 0x000FFFFF) >> 20;
			start_b = start_mb << 20;
			brcm_dram1_linux_mb = brcm_dram1_size_mb - start_mb;
			printk(KERN_WARNING "warning: 'memc1=%luM' starts "
			       " before splash memory bound (0x%lx);"
			       " adjusting to (memc1=%luM)\n",
			       orig_dram1, splash_bound, brcm_dram1_linux_mb);
		}
		printk(KERN_INFO "memc1: adding %luMB at %luMB "
		       "(0x%08lx@0x%08lx)",
		       brcm_dram1_linux_mb, (MEMC1_START >> 20) + start_mb,
		       brcm_dram1_linux_mb << 20, MEMC1_START + start_b);
		add_memory_region(MEMC1_START + start_b,
				  brcm_dram1_linux_mb << 20,
				  BOOT_MEM_RAM);
	}