static void
determine_machine(void)
{
	gMachine = MACHINE_UNKNOWN;

	int root = of_finddevice("/");
	char buffer[64];
	int length;

	// TODO : Probe other OpenFirmware platforms and set gMachine as needed

	if ((length = of_getprop(root, "device_type", buffer, sizeof(buffer) - 1))
		!= OF_FAILED) {
		buffer[length] = '\0';
		if (!strcasecmp("chrp", buffer))
			gMachine = MACHINE_CHRP;
		else if (!strcasecmp("bootrom", buffer))
			gMachine = MACHINE_MAC;
	} else
		gMachine = MACHINE_MAC;

	if ((length = of_getprop(root, "model", buffer, sizeof(buffer) - 1))
		!= OF_FAILED) {
		buffer[length] = '\0';
		if (!strcasecmp("pegasos", buffer))
			gMachine |= MACHINE_PEGASOS;
	}

	if ((length = of_getprop(root, "name", buffer, sizeof(buffer) - 1))
		!= OF_FAILED) {
		buffer[length] = '\0';
		if (!strcasecmp("openbiosteam,openbios", buffer))
			gMachine |= MACHINE_QEMU;
	}
}
Beispiel #2
0
status_t
ppc_openfirmware_pci_controller_init(void)
{
	char path[256];
	int cookie = 0;
	while (of_get_next_device(&cookie, 0, "pci", path, sizeof(path))
			== B_OK) {
dprintf("ppc_openfirmware_pci_controller_init(): pci device node: %s\n", path);
		// get the device node and the "compatible" property
		int deviceNode = of_finddevice(path);
		StringArrayPropertyValue compatible;
		status_t error = openfirmware_get_property(deviceNode, "compatible",
			compatible);
		if (error != B_OK) {
			dprintf("ppc_openfirmware_pci_controller_init: Failed to get "
				"\"compatible\" property for pci device: %s\n", path);
			continue;
		}

		// probe
		for (int i = 0; sProbeFunctions[i]; i++) {
			error = sProbeFunctions[i](deviceNode, compatible);
			if (error == B_OK)
				break;
		}
	}

	return B_OK;
}
Beispiel #3
0
ULONG findMem(APTR ofw, ULONG orig_MSR)
{
    ULONG volatile *mem=(APTR)(16*1024*1024);
    ULONG msr;
    int i;

    ULONG dev_handle, res, size;
    ULONG mem_info[2];
    
    asm volatile("mfmsr %0":"=r"(msr));

    while(ofw && ((ULONG)ofw < 0x10000000))
    {
	asm volatile("mtmsr %0"::"r"(orig_MSR));
	of_init(ofw);

	res = of_finddevice("/memory@0", &dev_handle);

	if (res)
		break;

	res = of_getprop(dev_handle, "reg", mem_info, sizeof(mem_info), &size);
	if (res) break;

	mem = (ULONG *)mem_info[1];

	break;
    }

    asm volatile("mtmsr %0"::"r"(msr));
    return (ULONG)mem;
}
Beispiel #4
0
status_t
of_init(int (*openFirmwareEntry)(void *))
{
	gCallOpenFirmware = openFirmwareEntry;

	gChosen = of_finddevice("/chosen");
	if (gChosen == OF_FAILED)
		return B_ERROR;

	return B_OK;
}
static int check_of_version(void)
{
	phandle oprom, chosen;
	char version[64];

	oprom = of_finddevice("/openprom");
	if (oprom == (phandle) -1)
		return 0;
	if (of_getprop(oprom, "model", version, sizeof(version)) <= 0)
		return 0;
	version[sizeof(version)-1] = 0;
	printf("OF version = '%s'\r\n", version);
	if (!string_match(version, "Open Firmware, 1.")
	    && !string_match(version, "FirmWorks,3."))
		return 0;
	chosen = of_finddevice("/chosen");
	if (chosen == (phandle) -1) {
		chosen = of_finddevice("/chosen@0");
		if (chosen == (phandle) -1) {
			printf("no chosen\n");
			return 0;
		}
	}
	if (of_getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
		printf("no mmu\n");
		return 0;
	}
	memory = (ihandle) of_call_prom("open", 1, 1, "/memory");
	if (memory == (ihandle) -1) {
		memory = (ihandle) of_call_prom("open", 1, 1, "/memory@0");
		if (memory == (ihandle) -1) {
			printf("no memory node\n");
			return 0;
		}
	}
	printf("old OF detected\r\n");
	return 1;
}
Beispiel #6
0
uval
rtas_instantiate(uval mem, uval msr)
{
	phandle pkg;
	sval ret;
	sval32 size;
	ihandle rtas;

	rtas_msr = msr;

	pkg = of_finddevice("/rtas");
	if (pkg == OF_FAILURE) return mem;

	ret = of_getprop(pkg, "rtas-size", &size, sizeof (size));
	assert(ret != OF_FAILURE, "of_getprop(rtas-size)");

	/* FIXME: Hack for SLOF.  We want OF to show rtas is present
	 * with size 0.  Linux detects hyperrtas, and uses LPAR
	 * interfaces, but won't use RTAS, which doesn't really exist,
	 * until we implement an RTAS layer.
	 */
	if (size==0)
		return 0;

	ret = call_of("open", 1, 1, &rtas, "/rtas");

	if (ret == OF_SUCCESS) {
		sval32 res[2];

		mem = ALIGN_UP(mem, PGSIZE);

		ret = call_of("call-method", 3, 2, res,
		      "instantiate-rtas", rtas, mem);

		assert(ret == OF_SUCCESS, "call-method(/instantiate-rtas)");
		hprintf("rtas located at 0x%x\n", res[1]);
		rtas_entry = res[1];
		rtas_base = mem;

		return ALIGN_UP(mem + size, PGSIZE);
	}
	return 0;
}
Beispiel #7
0
int s2_text_init(kernel_args *ka)
{
	int i;
	int screen_handle;

	screen_handle = of_finddevice("screen");
	if(screen_handle != 0) {
		of_getprop(screen_handle, "width", &screen_size_x, sizeof(screen_size_x));
		of_getprop(screen_handle, "height", &screen_size_y, sizeof(screen_size_y));
		of_getprop(screen_handle, "address", &framebuffer, sizeof(framebuffer));
		of_getprop(screen_handle, "depth", &screen_depth, sizeof(screen_depth));
	} else {
		// XXX hard coded
		framebuffer = (unsigned char *)0x96008000;
		screen_size_x = 1024;
		screen_size_y = 768;
	}

	back_color = 0x0;
	draw_color = 0xff;
	char_x = char_y = 0;

	num_cols = screen_size_x / CHAR_WIDTH;
	num_rows = screen_size_y / CHAR_HEIGHT;

	for(i = 0; i<screen_size_x * screen_size_y; i++) {
		framebuffer[i] = back_color;
	}

	ka->fb.enabled = 1;
	ka->fb.x_size = screen_size_x;
	ka->fb.y_size = screen_size_y;
	ka->fb.bit_depth = screen_depth;
	ka->fb.mapping.start = (unsigned long)framebuffer;
	ka->fb.mapping.size = ka->fb.x_size * ka->fb.y_size * ka->fb.bit_depth / 8;
	ka->fb.phys_addr.start = ka->fb.mapping.start;
	ka->fb.phys_addr.size = ka->fb.mapping.size;

	printf("framebuffer at %p\n", framebuffer);
	printf("screen_handle = 0x%x\n", screen_handle);

	return 0;
}
Beispiel #8
0
unsigned long
decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
		  RESIDUAL *residual, void *OFW_interface)
{
	int timer;
	extern unsigned long start;
	char *cp, ch;
	unsigned long i;
	BATU *u;
	BATL *l;
	unsigned long TotalMemory;
	unsigned long orig_MSR;
	int dev_handle;
	int mem_info[2];
	int res, size;
	unsigned char board_type;
	unsigned char base_mod;

	lines = 25;
	cols = 80;
	orig_x = 0;
	orig_y = 24;
	
	/*
	 * IBM's have the MMU on, so we have to disable it or
	 * things get really unhappy in the kernel when
	 * trying to setup the BATs with the MMU on
	 * -- Cort
	 */
	flush_instruction_cache();
	_put_HID0(_get_HID0() & ~0x0000C000);
	_put_MSR((orig_MSR = _get_MSR()) & ~0x0030);

#if defined(CONFIG_SERIAL_CONSOLE)
	com_port = (struct NS16550 *)NS16550_init(0);
#endif /* CONFIG_SERIAL_CONSOLE */
	vga_init(0xC0000000);

	if (residual)
	{
		/* Is this Motorola PPCBug? */
		if ((1 & residual->VitalProductData.FirmwareSupports) &&
		    (1 == residual->VitalProductData.FirmwareSupplier)) {
			board_type = inb(0x800) & 0xF0;

			/* If this is genesis 2 board then check for no
			 * keyboard controller and more than one processor.
			 */
			if (board_type == 0xe0) {	
				base_mod = inb(0x803);
				/* if a MVME2300/2400 or a Sitka then no keyboard */
				if((base_mod == 0xFA) || (base_mod == 0xF9) ||
				   (base_mod == 0xE1)) {
					keyb_present = 0;	/* no keyboard */
				}
			}
		}
		memcpy(hold_residual,residual,sizeof(RESIDUAL));
	} else {
		/* Assume 32M in the absence of more info... */
		TotalMemory = 0x02000000;
		/*
		 * This is a 'best guess' check.  We want to make sure
		 * we don't try this on a PReP box without OF
		 *     -- Cort
		 */
		while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) )
		{
			/* The MMU needs to be on when we call OFW */
			_put_MSR(orig_MSR);
			of_init(OFW_interface);

			/* get handle to memory description */
			res = of_finddevice("/memory@0", 
					    &dev_handle);
			// puthex(res);  puts("\n");
			if (res) break;
			
			/* get the info */
			// puts("get info = ");
			res = of_getprop(dev_handle, 
					 "reg", 
					 mem_info, 
					 sizeof(mem_info), 
					 &size);
			// puthex(res);  puts(", info = "); puthex(mem_info[0]);  
			// puts(" ");  puthex(mem_info[1]);   puts("\n");
			if (res) break;
			
			TotalMemory = mem_info[1];
			break;
		}
		hold_residual->TotalMemory = TotalMemory;
		residual = hold_residual;
		/* Turn MMU back off */
		_put_MSR(orig_MSR & ~0x0030);
        }

	/* assume the chunk below 8M is free */
	end_avail = (char *)0x00800000;

	/* tell the user where we were loaded at and where we
	 * were relocated to for debugging this process
	 */
	puts("loaded at:     "); puthex(load_addr);
	puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
	if ( (unsigned long)load_addr != (unsigned long)&start )
	{
		puts("relocated to:  "); puthex((unsigned long)&start);
		puts(" ");
		puthex((unsigned long)((unsigned long)&start + (4*num_words)));
		puts("\n");
	}

	if ( residual )
	{
		puts("board data at: "); puthex((unsigned long)residual);
		puts(" ");
		puthex((unsigned long)((unsigned long)residual + sizeof(RESIDUAL)));
		puts("\n");
		puts("relocated to:  ");
		puthex((unsigned long)hold_residual);
		puts(" ");
		puthex((unsigned long)((unsigned long)hold_residual + sizeof(RESIDUAL)));
		puts("\n");
	}

	/* we have to subtract 0x10000 here to correct for objdump including the
	   size of the elf header which we strip -- Cort */
	zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
	zimage_size = ZIMAGE_SIZE;

	if ( INITRD_OFFSET )
		initrd_start = load_addr - 0x10000 + INITRD_OFFSET;
	else
		initrd_start = 0;
	initrd_end = INITRD_SIZE + initrd_start;

	/*
	 * Find a place to stick the zimage and initrd and 
	 * relocate them if we have to. -- Cort
	 */
	avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
	puts("zimage at:     "); puthex((unsigned long)zimage_start);
	puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
	if ( (unsigned long)zimage_start <= 0x00800000 )
	{
		memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size );
		zimage_start = (char *)avail_ram;
		puts("relocated to:  "); puthex((unsigned long)zimage_start);
		puts(" ");
		puthex((unsigned long)zimage_size+(unsigned long)zimage_start);
		puts("\n");
		avail_ram += zimage_size;
	}

	/* relocate initrd */
	if ( initrd_start )
	{
		puts("initrd at:     "); puthex(initrd_start);
		puts(" "); puthex(initrd_end); puts("\n");
		if ( (unsigned long)initrd_start <= 0x00800000 )
		{
			memcpy( (void *)avail_ram,
				(void *)initrd_start, initrd_end-initrd_start );
			puts("relocated to:  ");
			initrd_end = (unsigned long) avail_ram + (initrd_end-initrd_start);
			initrd_start = (unsigned long)avail_ram;
			puthex((unsigned long)initrd_start);
			puts(" ");
			puthex((unsigned long)initrd_end);
			puts("\n");
		}
		avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end);
	}

	avail_ram = (char *)0x00400000;
	end_avail = (char *)0x00800000;
	puts("avail ram:     "); puthex((unsigned long)avail_ram); puts(" ");
	puthex((unsigned long)end_avail); puts("\n");

	if (keyb_present)
		CRT_tstc();  /* Forces keyboard to be initialized */

	puts("\nLinux/PPC load: ");
	timer = 0;
	cp = cmd_line;
	memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
	while ( *cp ) putc(*cp++);
	while (timer++ < 5*1000) {
		if (tstc()) {
			while ((ch = getc()) != '\n' && ch != '\r') {
				if (ch == '\b') {
					if (cp != cmd_line) {
						cp--;
						puts("\b \b");
					}
				} else {
					*cp++ = ch;
					putc(ch);
				}
			}
			break;  /* Exit 'timer' loop */
		}
		udelay(1000);  /* 1 msec */
	}
	*cp = 0;
	puts("\n");

	puts("Uncompressing Linux...");
	gunzip(0, 0x400000, zimage_start, &zimage_size);
	puts("done.\n");
	
	{
		struct bi_record *rec;
	    
		rec = (struct bi_record *)PAGE_ALIGN(zimage_size);
	    
		rec->tag = BI_FIRST;
		rec->size = sizeof(struct bi_record);
		rec = (struct bi_record *)((unsigned long)rec + rec->size);

		rec->tag = BI_BOOTLOADER_ID;
		memcpy( (void *)rec->data, "prepboot", 9);
		rec->size = sizeof(struct bi_record) + 8 + 1;
		rec = (struct bi_record *)((unsigned long)rec + rec->size);
	    
		rec->tag = BI_MACHTYPE;
		rec->data[0] = _MACH_prep;
		rec->data[1] = 1;
		rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
		rec = (struct bi_record *)((unsigned long)rec + rec->size);
	    
		rec->tag = BI_CMD_LINE;
		memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
		rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
		rec = (struct bi_record *)((ulong)rec + rec->size);
		
		rec->tag = BI_LAST;
		rec->size = sizeof(struct bi_record);
		rec = (struct bi_record *)((unsigned long)rec + rec->size);
	}
	puts("Now booting the kernel\n");
	return (unsigned long)hold_residual;
}
Beispiel #9
0
void _start(int arg1, int arg2, void *openfirmware)
{
	int chosen;
	
	of_init(openfirmware);

	/* open the input and output handle */
	chosen = of_finddevice("/chosen");
	of_getprop(chosen, "stdin", &of_input_handle, sizeof(of_input_handle));
	of_getprop(chosen, "stdout", &of_output_handle, sizeof(of_output_handle));

	puts("this is a test\n");

	init_serial();

restart:
	puts("waiting for command\n");

	{
		int base_address;
		int entry_point;
		int length;
		int command;
		unsigned char *ptr;
		void (*func)(int, int, void *);

		serial_read_int32(&command);
		if(command != 0x99) {
			puts("bad command, restarting\n");
			goto restart;
		}

		serial_read_int32(&base_address);
		serial_read_int32(&length);
		serial_read_int32(&entry_point);

		puts("read base and length, claiming\n");

		puts("base ");
		write_hex(base_address);
		puts("\nlength ");
		write_hex(length);
		puts("\nentry_point ");
		write_hex(entry_point);
		puts("\n");

		ptr = (void *)base_address;

		of_claim(base_address, length, 0);

		puts("reading data\n");

		serial_read(ptr, length);	

		puts("done reading data, calling function\n");

		func = (void *)entry_point;
		func(arg1, arg2, openfirmware);
	}

	of_exit();
}
Beispiel #10
0
static status_t
find_physical_memory_ranges(size_t &total)
{
	int memory;
	dprintf("checking for memory...\n");
	if (of_getprop(gChosen, "memory", &memory, sizeof(int)) == OF_FAILED)
		return B_ERROR;
	int package = of_instance_to_package(memory);

	total = 0;

	// Memory base addresses are provided in 32 or 64 bit flavors
	// #address-cells and #size-cells matches the number of 32-bit 'cells'
	// representing the length of the base address and size fields
	int root = of_finddevice("/");
	int32 regAddressCells = of_address_cells(root);
	int32 regSizeCells = of_size_cells(root);
	if (regAddressCells == OF_FAILED || regSizeCells == OF_FAILED) {
		dprintf("finding base/size length counts failed, assume 32-bit.\n");
		regAddressCells = 1;
		regSizeCells = 1;
	}

	// NOTE : Size Cells of 2 is possible in theory... but I haven't seen it yet.
	if (regAddressCells > 2 || regSizeCells > 1) {
		panic("%s: Unsupported OpenFirmware cell count detected.\n"
		"Address Cells: %" B_PRId32 "; Size Cells: %" B_PRId32
		" (CPU > 64bit?).\n", __func__, regAddressCells, regSizeCells);
		return B_ERROR;
	}

	// On 64-bit PowerPC systems (G5), our mem base range address is larger
	if (regAddressCells == 2) {
		struct of_region<uint64> regions[64];
		int count = of_getprop(package, "reg", regions, sizeof(regions));
		if (count == OF_FAILED)
			count = of_getprop(memory, "reg", regions, sizeof(regions));
		if (count == OF_FAILED)
			return B_ERROR;
		count /= sizeof(regions[0]);

		for (int32 i = 0; i < count; i++) {
			if (regions[i].size <= 0) {
				dprintf("%ld: empty region\n", i);
				continue;
			}
			dprintf("%" B_PRIu32 ": base = %" B_PRIu64 ","
				"size = %" B_PRIu32 "\n", i, regions[i].base, regions[i].size);

			total += regions[i].size;

			if (insert_physical_memory_range((addr_t)regions[i].base,
					regions[i].size) != B_OK) {
				dprintf("cannot map physical memory range "
					"(num ranges = %" B_PRIu32 ")!\n",
					gKernelArgs.num_physical_memory_ranges);
				return B_ERROR;
			}
		}
		return B_OK;
	}

	// Otherwise, normal 32-bit PowerPC G3 or G4 have a smaller 32-bit one
	struct of_region<uint32> regions[64];
	int count = of_getprop(package, "reg", regions, sizeof(regions));
	if (count == OF_FAILED)
		count = of_getprop(memory, "reg", regions, sizeof(regions));
	if (count == OF_FAILED)
		return B_ERROR;
	count /= sizeof(regions[0]);

	for (int32 i = 0; i < count; i++) {
		if (regions[i].size <= 0) {
			dprintf("%ld: empty region\n", i);
			continue;
		}
		dprintf("%" B_PRIu32 ": base = %" B_PRIu32 ","
			"size = %" B_PRIu32 "\n", i, regions[i].base, regions[i].size);

		total += regions[i].size;

		if (insert_physical_memory_range((addr_t)regions[i].base,
				regions[i].size) != B_OK) {
			dprintf("cannot map physical memory range "
				"(num ranges = %" B_PRIu32 ")!\n",
				gKernelArgs.num_physical_memory_ranges);
			return B_ERROR;
		}
	}

	return B_OK;
}