diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/SLOF/board-qemu | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/SLOF/board-qemu')
51 files changed, 5032 insertions, 0 deletions
diff --git a/roms/SLOF/board-qemu/Makefile b/roms/SLOF/board-qemu/Makefile new file mode 100644 index 00000000..29ee016a --- /dev/null +++ b/roms/SLOF/board-qemu/Makefile @@ -0,0 +1,73 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2011 IBM Corporation +# * All rights reserved. +# * This program and the accompanying materials +# * are made available under the terms of the BSD License +# * which accompanies this distribution, and is available at +# * http://www.opensource.org/licenses/bsd-license.php +# * +# * Contributors: +# *     IBM Corporation - initial implementation +# ****************************************************************************/ + +BOARD_TARGETS = tools_build romfs_build clients_build stage1 subdirs + +SUBDIRS = slof + +COMMON_LIBS = libc libbootmsg libbases libnvram libelf libhvcall libvirtio libusb \ +              libveth libe1k + +all: $(BOARD_TARGETS) +	$(MAKE) boot_rom.bin + +.PHONY : subdirs $(SUBDIRS) clean distclean + +include config +include Makefile.dirs +include $(TOPCMNDIR)/make.rules +include $(TOPCMNDIR)/Makefile.gen + +subdirs: $(SUBDIRS) + +$(SUBDIRS): common-libs +	@echo " ====== Building $@ ======" +	$(MAKE) -C $@ $(MAKEARG) RELEASE=-DRELEASE=\"\\\"$(RELEASE)\\\"\" + +stage1:	common-libs +	@echo " ====== Building llfw ======" +	$(MAKE) -C llfw RELEASE=-DRELEASE=\"\\\"$(RELEASE)\\\"\" + +clean_here: +	rm -f ../slof/OF.ffs +	rm -f ../boot_rom.bin + +clean:	clean_here clean_gen +	@for dir in $(SUBDIRS); do \ +		$(MAKE) -C $$dir clean || exit 1; \ +	done +	rm -f ../boot_rom.bin  +	@$(MAKE) -C llfw clean + +distclean:	clean_here distclean_gen +	@for dir in $(SUBDIRS); do \ +		$(MAKE) -C $$dir distclean || exit 1; \ +	done +	rm -f ../boot_rom.bin  +	$(MAKE) -C llfw clean + +.driver_dirs: +	@rm -rf ../driver-$(RELEASE) +	@mkdir -p ../driver-$(RELEASE) + +.tar_gz:	.driver_dirs +	@mv ../boot_rom.bin ../driver-$(RELEASE)/$(RELEASE)-slof.bin +	@cp ../VERSION ../driver-$(RELEASE) +	@cp changes.txt ../driver-$(RELEASE) +	@cd ../driver-$(RELEASE) && md5sum * > md5sum.txt +	@chmod 644 ../driver-$(RELEASE)/* +	@mv ../driver-$(RELEASE) ../driver-$(RELEASE)-`date +%Y-%h%d` +	@tar czf ../driver-$(RELEASE)-`date +%Y-%h%d`.tar.gz \ +		../driver-$(RELEASE)-`date +%Y-%h%d` > /dev/null  2>&1 +	@rm -rf ../driver-$(RELEASE)-`date +%Y-%h%d` + +driver:		driver_prep clean .tar_gz diff --git a/roms/SLOF/board-qemu/Makefile.dirs b/roms/SLOF/board-qemu/Makefile.dirs new file mode 100644 index 00000000..1493d3bf --- /dev/null +++ b/roms/SLOF/board-qemu/Makefile.dirs @@ -0,0 +1,41 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2008 IBM Corporation +# * All rights reserved. +# * This program and the accompanying materials +# * are made available under the terms of the BSD License +# * which accompanies this distribution, and is available at +# * http://www.opensource.org/licenses/bsd-license.php +# * +# * Contributors: +# *     IBM Corporation - initial implementation +# ****************************************************************************/ +# +# This sub-Makefile contains the directory configuration variables. +# It can be included from all board specific subdirectories. +# + +# The board specific top directory: +export TOPBRDDIR ?= $(shell while ! test -e Makefile.dirs ; do cd .. ; done ; pwd ) + +# The board specific directories: +export INCLBRDDIR ?= $(TOPBRDDIR)/include +export LLFWBRDDIR ?= $(TOPBRDDIR)/llfw +export RTASBRDDIR ?= $(TOPBRDDIR)/rtas +export SLOFBRDDIR ?= $(TOPBRDDIR)/slof +export ROMFSBRDDIR ?=  $(TOPBRDDIR)/romfs + +# The common top directory: +export TOPCMNDIR ?= $(shell cd $(TOPBRDDIR)/.. && pwd) + +# The common directories: +export INCLCMNDIR ?= $(TOPCMNDIR)/include +export LLFWCMNDIR ?= $(TOPCMNDIR)/llfw +export RTASCMNDIR ?= $(TOPCMNDIR)/rtas +export SLOFCMNDIR ?= $(TOPCMNDIR)/slof +export ROMFSCMNDIR ?=  $(TOPCMNDIR)/romfs + +export LIBCMNDIR ?= $(TOPCMNDIR)/lib + +export TOOLSDIR ?= $(TOPCMNDIR)/tools +export CLIENTSDIR ?= $(TOPCMNDIR)/clients +export OTHERLICENCEDIR ?= $(TOPCMNDIR)/other-licence diff --git a/roms/SLOF/board-qemu/config b/roms/SLOF/board-qemu/config new file mode 100644 index 00000000..f1940914 --- /dev/null +++ b/roms/SLOF/board-qemu/config @@ -0,0 +1,7 @@ +BOARD=qemu +TARG=ppc64 +export FLAG="-DRTAS_NVRAM -DBROKEN_SC1 -DDHCPARCH=0x0C " +export CPUARCH=ppcp7 +export CPUARCHDEF=-DCPU_PPCP7 +#export SNK_BIOSEMU_APPS=1 +FLASH_SIZE=8388608 diff --git a/roms/SLOF/board-qemu/include/hw.h b/roms/SLOF/board-qemu/include/hw.h new file mode 100644 index 00000000..27117c3f --- /dev/null +++ b/roms/SLOF/board-qemu/include/hw.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +uint16_t bswap16_load(uint64_t addr) ; +uint32_t bswap32_load(uint64_t addr) ; + +void bswap16_store(uint64_t addr, uint16_t val) ; +void bswap32_store(uint64_t addr, uint32_t val) ; + +uint8_t load8_ci(uint64_t addr) ; +uint16_t load16_ci(uint64_t addr) ; +uint32_t load32_ci(uint64_t addr) ; +uint64_t load64_ci(uint64_t addr) ; + +void store8_ci(uint64_t  addr, uint8_t val) ; +void store16_ci(uint64_t  addr, uint16_t val) ; +void store32_ci(uint64_t  addr, uint32_t val) ; +void store64_ci(uint64_t  addr, uint64_t val) ; diff --git a/roms/SLOF/board-qemu/include/nvramlog.h b/roms/SLOF/board-qemu/include/nvramlog.h new file mode 100644 index 00000000..d1302559 --- /dev/null +++ b/roms/SLOF/board-qemu/include/nvramlog.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * Copyright (c) 2004, 2011 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef NVRAMLOG_H +	#define NVRAMLOG_H + +/* ---------------------------------------------------------------------------- + *	NVRAM Log-Partition header design: + * + *	Partition Header + *	00h	- signature	( 1 byte) + *	01h	- checksum	( 1 byte) + *	02h	- length	( 2 byte) value = 1st_byte*256 + 2nd_byte + *	04h	- name		(12 byte) + *	space for partiton header = 16 byte + * + *	Log Header + *	10h	- offset	( 2 byte) from Partition Header to Data Section + *	12h	- flags		( 2 byte) control flags + *	14h	- pointer	( 4 byte) pointer to first free byte in Data Section + *					  relative to the beginning of the data section + *	18h	- zero		( 32 byte) reserved as stack for four  64 bit register + *	38h - reserved		(  8 byte) reserved for 64 bit CRC (not implemented yet) + *	space for header = 64 byte + *	Data Section + *	40h	- cyclic data + * -------------------------------------------------------------------------------- */ + +	// initial values +	#define LLFW_LOG_BE0_SIGNATURE		0x51			// signature for general firmware usage +	#define LLFW_LOG_BE0_NAME_PREFIX	0x69626D2C		// first 4 bytes of name: "ibm," +	#define LLFW_LOG_BE0_NAME		0x435055306C6F6700	// remaining 8 bytes	: "CPU0log\0" +	#define LLFW_LOG_BE0_LENGTH		0x200			// Partition length in block of 16 bytes +	#define LLFW_LOG_BE0_DATA_OFFSET	0x40			// offset in bytes between header and data +	#define LLFW_LOG_BE0_FLAGS		0			// unused + +	#define LLFW_LOG_BE1_SIGNATURE		0x51			// signature for general firmware usage +	#define LLFW_LOG_BE1_NAME_PREFIX	0x69626D2C		// first 4 bytes of name: "ibm," +	#define LLFW_LOG_BE1_NAME		0x435055316C6F6700	// remaining 8 bytes	: "CPU1log\0\0" +	#define LLFW_LOG_BE1_LENGTH		0x80			// Partition length in block of 16 bytes +	#define LLFW_LOG_BE1_DATA_OFFSET	0x40			// offset in bytes between header and data +	#define LLFW_LOG_BE1_FLAGS		0x0			// unused + +	// positions of the initial values +	#define LLFW_LOG_POS_CHECKSUM	0x01			// 1 +	#define LLFW_LOG_POS_LENGTH	0x02			// 2 +	#define LLFW_LOG_POS_NAME	0x04			// 4 +	#define LLFW_LOG_POS_DATA_OFFSET 0x10			// 16 +	#define LLFW_LOG_POS_FLAGS	0x12			// 18 +	#define LLFW_LOG_POS_POINTER	0x14			// 20 + +	// NVRAM info +	#define NVRAM_EMPTY_PATTERN	0x0000000000000000	// Pattern (64-bit) used to overwrite NVRAM + +#endif diff --git a/roms/SLOF/board-qemu/include/product.h b/roms/SLOF/board-qemu/include/product.h new file mode 100644 index 00000000..819d6eda --- /dev/null +++ b/roms/SLOF/board-qemu/include/product.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * Copyright (c) 2004, 2011 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef _PRODUCT_H +#define _PRODUCT_H + +/* This is also the name which is also put in the flash and should + * therefore not excedd the length of 32 bytes */ +#define PRODUCT_NAME "QEMU" + +/* Generic identifier used in the flash */ +#define FLASHFS_MAGIC "magic123" + +/* Magic identifying the platform */ +#define FLASHFS_PLATFORM_MAGIC "qemu0" + +/* also used in the flash */ +#define FLASHFS_PLATFORM_REVISION "1" + +#define BOOT_MESSAGE  "Press \"s\" to enter Open Firmware.\r\n\r\n\0" + +#endif diff --git a/roms/SLOF/board-qemu/include/southbridge.h b/roms/SLOF/board-qemu/include/southbridge.h new file mode 100644 index 00000000..1cdb422c --- /dev/null +++ b/roms/SLOF/board-qemu/include/southbridge.h @@ -0,0 +1,19 @@ +/****************************************************************************** + * Copyright (c) 2011 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +/* Not used */ +#define SB_NVRAM_adr 	0 +#define SB_FLASH_adr 	0 +#define FLASH_LENGTH 	0 +#define SB_MAILBOX_adr	0 + +#define SECONDARY_CPUS_STOPPED diff --git a/roms/SLOF/board-qemu/llfw/Cboot.S b/roms/SLOF/board-qemu/llfw/Cboot.S new file mode 100644 index 00000000..d22f3c93 --- /dev/null +++ b/roms/SLOF/board-qemu/llfw/Cboot.S @@ -0,0 +1,18 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +	.org 0 + +	/* Boot Information, hardcoded to ColdReset */ +	.quad	1 +	/* start address */ +	.quad	0x100 diff --git a/roms/SLOF/board-qemu/llfw/Makefile b/roms/SLOF/board-qemu/llfw/Makefile new file mode 100644 index 00000000..c83f21e3 --- /dev/null +++ b/roms/SLOF/board-qemu/llfw/Makefile @@ -0,0 +1,59 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2011 IBM Corporation +# * All rights reserved. +# * This program and the accompanying materials +# * are made available under the terms of the BSD License +# * which accompanies this distribution, and is available at +# * http://www.opensource.org/licenses/bsd-license.php +# * +# * Contributors: +# *     IBM Corporation - initial implementation +# ****************************************************************************/ + +include ../../make.rules + +CPPFLAGS	= -I$(INCLBRDDIR) -I$(INCLCMNDIR) -I$(INCLCMNDIR)/$(CPUARCH) \ +		  -I$(LIBCMNDIR)/libc/include +CFLAGS		+= -fno-builtin $(FLAG) $(CPPFLAGS) -O2  -msoft-float $(MAMBO) +CFLAGS		+= $(BOOT) $(IOCONF) -Wa,-mregnames $(RELEASE) $(CPUARCHDEF) -Wall +ASFLAGS         = $(BOOT) $(IOCONF) $(RELEASE)$(CPUARCHDEF)  -Wa,-mregnames +LDFLAGS1	= -nostdlib -e__start -Tstage2.lds -N -Ttext=0x100 + + +STG1OBJ		 = startup.o version.o boot_abort.o romfs.o io_generic.o board_io.o  +STG1OBJ		 += stage2_head.o stage2.o comlib.o romfs_wrap.o nvramlog.o + +.PHONY: version.S + +all: stage1.bin Cboot.o + +stage1.bin:	$(STG1OBJ) $(LIBCMNDIR)/libelf.a $(LIBCMNDIR)/libc.a \ +		$(LIBCMNDIR)/libhvcall.a +		$(LD) $(LDFLAGS1) -o stage1.elf $^ +		$(OBJCOPY) -O binary stage1.elf $@ + +romfs.o:	../../llfw/romfs.S +		$(CC) $(CFLAGS) -c ../../llfw/romfs.S + +boot_abort.o:	../../llfw/boot_abort.S +		$(CC) $(CFLAGS) -c ../../llfw/boot_abort.S + +nvramlog.o:	../../llfw/nvramlog.S +		$(CC) $(CFLAGS) -c ../../llfw/nvramlog.S + +include $(LLFWCMNDIR)/clib/Makefile.inc + +include $(LLFWCMNDIR)/io_generic/Makefile.inc + +romfs_wrap.o:	../../llfw/romfs_wrap.c +		$(CC) $(CFLAGS) -c ../../llfw/romfs_wrap.c + +Cboot.o: Cboot.S +		$(CC) $(CFLAGS) -c $^ +		$(OBJCOPY) -O binary Cboot.o Cboot.bin + +%.o: %.S +		$(CC) $(CFLAGS) -c $^ + +clean: +		rm -f *.o *.bin *.elf diff --git a/roms/SLOF/board-qemu/llfw/board_io.S b/roms/SLOF/board-qemu/llfw/board_io.S new file mode 100644 index 00000000..7d572ab1 --- /dev/null +++ b/roms/SLOF/board-qemu/llfw/board_io.S @@ -0,0 +1,46 @@ +/****************************************************************************** + * Copyright (c) 2004, 2011 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +#include <macros.h> +#include <cpu.h> + +	.text + +/**************************************************************************** + * prints one character to serial console + * + * Input: + * R3 - character + * + * Returns: - + * + * Modifies Registers: + * R3, R4, R5, R6, R7 + ****************************************************************************/ +ENTRY(io_putchar) +	sldi	r6,r3,(24+32) +	li	r3,0x58 +	li	r4,0 +	li	r5,1 +	.long 0x44000022 +	blr +	 +ENTRY(io_getchar) +	mr	r10,r3 +	li	r3,0x54 +	li	r4,0 +	.long 0x44000022 +	mr.	r3,r4 +	beq	1f +	srdi	r3,r5,(24+32) +	stb	r3,0(r10) +1:	blr diff --git a/roms/SLOF/board-qemu/llfw/stage2.c b/roms/SLOF/board-qemu/llfw/stage2.c new file mode 100644 index 00000000..ef6ea355 --- /dev/null +++ b/roms/SLOF/board-qemu/llfw/stage2.c @@ -0,0 +1,205 @@ +/****************************************************************************** + * Copyright (c) 2004, 2011 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdint.h> +#include <xvect.h> +#include <hw.h> +#include <stdio.h> +#include <romfs.h> +#include "memmap.h" +#include "stage2.h" +#include <termctrl.h> +#include "product.h" +#include "calculatecrc.h" +#include <cpu.h> +#include <libelf.h> +#include <string.h> +#include "../lib/libhvcall/libhvcall.h" + +#define DEBUG(fmt...) +//#define DEBUG(fmt...) printf(fmt) + +uint64_t gVecNum; + +uint64_t exception_stack_frame; + +typedef void (*pInterruptFunc_t) (void); + +pInterruptFunc_t vectorTable[0x2E << 1]; + +extern void proceedInterrupt(void); + +/* Prototypes for functions of this file */ +void c_interrupt(uint64_t vecNum); +void set_exceptionVector(int num, void *func); +void early_c_entry(uint64_t start_addr, uint64_t fdt_addr); + + +static void exception_forward(void) +{ +	uint64_t val; + +	if (*(uint64_t *) XVECT_M_HANDLER) { +		proceedInterrupt(); +	} + +	printf("\r\n exception %llx ", gVecNum); +	asm volatile ("mfsrr0	%0":"=r" (val):); +	printf("\r\nSRR0 = %08llx%08llx ", val >> 32, val); +	asm volatile ("mfsrr1	%0":"=r" (val):); +	printf(" SRR1 = %08llx%08llx ", val >> 32, val); + +	asm volatile ("mfsprg	%0,2":"=r" (val):); +	printf("\r\nSPRG2 = %08llx%08llx ", val >> 32, val); +	asm volatile ("mfsprg	%0,3":"=r" (val):); +	printf(" SPRG3 = %08llx%08llx \r\n", val >> 32, val); +	while (1); +} + +void c_interrupt(uint64_t vecNum) +{ +	gVecNum = vecNum; +	if (vectorTable[vecNum >> 7]) { +		vectorTable[vecNum >> 7] (); +	} else { +		exception_forward(); +	} +} + +void set_exceptionVector(int num, void *func) +{ +	vectorTable[num >> 7] = (pInterruptFunc_t) func; +} + +static void load_file(uint64_t destAddr, char *name, uint64_t maxSize, +		      uint64_t romfs_base) +{ +	uint64_t cnt; +	struct romfs_lookup_t fileInfo; +	int rc; + +	rc = c_romfs_lookup(name, romfs_base, &fileInfo); +	if (rc) { +		printf("Cannot find romfs file %s\n", name); +		return; +	} +	DEBUG("Found romfs file %s\n", name); +	if (maxSize) { +		cnt = maxSize; +	} else { +		cnt = fileInfo.size_data; +	} +	memcpy((void *)destAddr, (void *)fileInfo.addr_data, cnt); +	flush_cache((void *) destAddr, fileInfo.size_data); +} + +extern void print_version(void); + +/*************************************************************************** + * Function: early_c_entry + * Input   : start_addr + * + * Description: + **************************************************************************/ +void early_c_entry(uint64_t start_addr, uint64_t fdt_addr) +{ +	struct romfs_lookup_t fileInfo; +	void (*ofw_start) (uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); +	uint64_t *boot_info; +	uint64_t romfs_base, paflof_base; +	// romfs header values +	// struct stH *header = (struct stH *) (start_addr + 0x28); +	// uint64_t flashlen = header->flashlen; +	unsigned long ofw_addr[2]; +	int rc; +	extern char __executable_start; +	extern char __etext; + +	/* +	 * If we run on a broken environment, we need to patch our own sc 1 +	 * calls to be able to trap hypercalls. This does not cover RTAS or +	 * any payload we will load yet. +	 */ +	if (patch_broken_sc1(&__executable_start, &__etext, NULL)) { +		/* We are running in PR KVM on top of pHyp. Print all output +		   we missed to print so far again to fake identical behavior */ +		printf("\n\r\nSLOF"); +		print_version(); +	} + +	if (fdt_addr == 0) { +		puts("ERROR: Flatten device tree not available!"); +	} + +	/* Hack: Determine base for "ROM filesystem" in memory... +	 * QEMU loads the FDT at the top of the available RAM, so we place +	 * the ROMFS just underneath. */ +	romfs_base = (fdt_addr - 0x410000) & ~0xffffLL; +	memcpy((char *)romfs_base, 0, 0x400000); + +	exception_stack_frame = 0; + +	printf(" Press \"s\" to enter Open Firmware.\r\n\r\n"); + +	DEBUG("  [c_romfs_lookup at %p]\n", c_romfs_lookup); +	rc = c_romfs_lookup("bootinfo", romfs_base, &fileInfo); +	if (rc) +		printf("  !!! roomfs lookup(bootinfo) = %d\n", rc); +	boot_info = (uint64_t *) fileInfo.addr_data; +	boot_info[1] = start_addr; +	load_file(0x100, "xvect", 0, romfs_base); +	rc = c_romfs_lookup("ofw_main", romfs_base, &fileInfo); +	if (rc) +		printf("  !!! roomfs lookup(bootinfo) = %d\n", rc); + +	DEBUG("  [ofw_main addr hdr  0x%lx]\n", fileInfo.addr_header); +	DEBUG("  [ofw_main addr data 0x%lx]\n", fileInfo.addr_data); +	DEBUG("  [ofw_main size data 0x%lx]\n", fileInfo.size_data); +	DEBUG("  [ofw_main flags     0x%lx]\n", fileInfo.flags); +	DEBUG("  [hdr: 0x%08lx 0x%08lx]\n  [     0x%08lx 0x%08lx]\n", +	       ((uint64_t *)fileInfo.addr_header)[0], +	       ((uint64_t *)fileInfo.addr_header)[1], +	       ((uint64_t *)fileInfo.addr_header)[2], +	       ((uint64_t *)fileInfo.addr_header)[3]); + +	/* Assume that paflof and SNK need ca. 31 MiB RAM right now. +	 * TODO: Use value from ELF file instead */ +	paflof_base = romfs_base - 0x1F00000 + 0x100; +	if ((int64_t)paflof_base <= 0LL) { +		puts("ERROR: Not enough memory for Open Firmware"); +	} +	rc = elf_load_file_to_addr((void *)fileInfo.addr_data, (void*)paflof_base, +				   ofw_addr, NULL, flush_cache); +	DEBUG("  [load_elf_file returned %d]\n", rc); + +	ofw_start = +	    (void (*)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t)) +	    &ofw_addr; +	// re-enable the cursor +	printf("%s%s", TERM_CTRL_RESET, TERM_CTRL_CRSON); +	DEBUG("  [ofw_start=%p ofw_addr=0x%lx]\n", ofw_start, ofw_addr[0]); +	ofw_addr[1] = ofw_addr[0]; +	/* Call the Open Firmware layer with ePAPR-style calling conventions: +	 * r3 = R3 Effective address of the device tree image. Note: this +	 *      address must be 8-byte aligned in memory. +	 * r4 = implementation dependent, we use it for ROMFS base address +	 * r5 = 0 +	 * r6 = 0x65504150 -- ePAPR magic value-to distinguish from +	 *      non-ePAPR-compliant firmware +	 * r7 = size of Initially Mapped Area +	 *      (right now we assume everything from 0 to the FDT is the IMA) +	 */ +	asm volatile("isync; sync;" : : : "memory"); +	ofw_start(fdt_addr, romfs_base, 0, 0x65504150, fdt_addr); +	asm volatile("isync; sync;" : : : "memory"); +	// never return +} diff --git a/roms/SLOF/board-qemu/llfw/stage2.h b/roms/SLOF/board-qemu/llfw/stage2.h new file mode 100644 index 00000000..9ce3c820 --- /dev/null +++ b/roms/SLOF/board-qemu/llfw/stage2.h @@ -0,0 +1,23 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef __STAGE2_H +#define __STAGE2_H + +#ifndef __ASSEMBLER__ + +#include <stddef.h> + +void u4memInit(void); + +#endif		/* __ASSEMBLER__ */ +#endif		/* __STAGE2_H */ diff --git a/roms/SLOF/board-qemu/llfw/stage2.lds b/roms/SLOF/board-qemu/llfw/stage2.lds new file mode 100644 index 00000000..e060dd18 --- /dev/null +++ b/roms/SLOF/board-qemu/llfw/stage2.lds @@ -0,0 +1,59 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +OUTPUT_FORMAT("elf64-powerpc", "elf64-powerpc", "elf64-powerpc") +OUTPUT_ARCH(powerpc:common64) + +/* set the entry point */ +ENTRY ( __start ) + +SECTIONS { +	__executable_start = .; + +	.text : { +		*(.text) +	} + +	__etext = .; + +	. = ALIGN(8); + +	.data : { +		*(.data) +		*(.rodata .rodata.*) +		*(.got1) +		*(.sdata) +		*(.opd) +	} + +	/* FIXME bss at end ??? */ + +	. = ALIGN(8); +	__bss_start = .; +	.bss : { +		*(.sbss) *(.scommon) +		*(.dynbss) +		*(.bss) +	} + +	. = ALIGN(8); +	__bss_end = .; +	__bss_size = (__bss_end - __bss_start); + +	__toc_start = .; +	.got : +	{ +		 *(.toc .got) +	} +	. = ALIGN(8); +	__toc_end = .; +} diff --git a/roms/SLOF/board-qemu/llfw/stage2_head.S b/roms/SLOF/board-qemu/llfw/stage2_head.S new file mode 100644 index 00000000..c56b117c --- /dev/null +++ b/roms/SLOF/board-qemu/llfw/stage2_head.S @@ -0,0 +1,95 @@ +/****************************************************************************** + * Copyright (c) 2004, 2011 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +#include "macros.h" +#include "../../llfw/boot_abort.h" + +/*#################### defines #####################*/ +#define STACK_SIZE   0x4000 + +/*#################### code ########################*/ +	.text +	.globl .gluon_c_entry +	.globl __toc_start +	.globl __toc_end +	.globl __bss_start +	.globl __bss_size +	.globl __start + +ASM_ENTRY(__startC) +	/* clear out bss section                */ +	LOAD64(r3, (__bss_start - 8)) +	LOAD64(r4, __bss_size) + +	/* divide __bss_size by 8 to get number */ +	/* of dwords to clear                   */ +	srwi.	r4, r4, 3 +	beq	bsscdone +	li	r5, 0 +	mtctr	r4 +bssc:	stdu	r5, 8(r3) +	bdnz	bssc +bsscdone: +	/* setup stack                          */ +	LOAD64(r1, __stack_end + STACK_SIZE) + +	/* save return address beside stack     */ +	addi	r3, r1, 128 +	mflr	r0 +	std	r0, 0(r3) + +	/* setup toc                            */ +	bl	toc_init + +	/* ------------------------------------ */ +	/* jump to c-code                       */ +	/* r31 = fdt                    - r5    */ +	/* ------------------------------------ */ +	li	r3, r0 +	mr	r4, r31 +	bl	.early_c_entry + +	/* return to caller...                  */ +	LOAD64(r1, __stack_end + STACK_SIZE) +	addi	r1, r1, 128 +	ld	r3, 0(r1) +	mtlr	r3 +	blr + +	/* #################################### */ +	/* Basic Additional Functions           */ +	/* for extended lib functions see       */ +	/* external library                     */ +	/* #################################### */ +	.align 	2 + +	/* ------------------------------------ */ +	/* updates toc in r2                    */ +	/* ------------------------------------ */ +ASM_ENTRY(toc_init) +	LOAD64(r2, __toc_start) +	addi	r2,r2,0x4000 +	addi	r2,r2,0x4000 +	blr + +	/* ------------------------------------ */ +	/* stores arg#1 in r27 and stops        */ +	/* ------------------------------------ */ +ENTRY(do_panic) +ENTRY(halt_sys) +	BOOT_ABORT_R3HINT(ABORT_CANIO, ALTBOOT, msg_e_ierror); + +	.section ".bss" +	.balign STACK_SIZE +__stack_end: +	.space STACK_SIZE +	.text diff --git a/roms/SLOF/board-qemu/llfw/startup.S b/roms/SLOF/board-qemu/llfw/startup.S new file mode 100644 index 00000000..bbd3ce3a --- /dev/null +++ b/roms/SLOF/board-qemu/llfw/startup.S @@ -0,0 +1,240 @@ +/****************************************************************************** + * Copyright (c) 2004, 2011 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +/* SLOF for QEMU -- boot code. + * Initial entry point + */ + +#include <xvect.h> +#include <cpu.h> +#include <macros.h> + +	/* qemu entry: +	 * +	 * __start loaded at 0x100 +	 * +	 * CPU 0 starts at 0 with GPR3 pointing to the flat devtree +	 * +	 * All other CPUs are held in stopped state by qemu and are +	 * started via RTAS +	 */ +	.text +	.globl __start +__start: +	b	_start +	.long 0xDEADBEE0 +	.long 0x0       /* size */  +	.long 0x0       /* crc  */ +	.long relTag - __start + +	/* Some exception vectors +	 *	 +	 * FIXME: Also need 0280, 0380, 0f20, etc. +	 */ + +	.irp i, 0x0100,0x0180,0x0200,0x0280,0x0300,0x0380,0x0400,0x0500, \ +	        0x0600,0x0700,0x0800,0x0900,0x0a00,0x0b00,0x0c00,0x0d00, \ +	        0x0e00,0x0f00,0x1000,0x1100,0x1200,0x1300,0x1400,0x1500, \ +	        0x1600,0x1700, \ +		0x1800,0x1900,0x1a00,0x1b00,0x1c00,0x1d00,0x1e00,0x1f00, \ +		0x2000,0x2100,0x2200,0x2300,0x2400,0x2500,0x2600,0x2700, \ +		0x2800,0x2900,0x2a00,0x2b00,0x2c00,0x2d00,0x2e00 +	. = \i + +	/* enable this if you get exceptions before the console works    */ +	/* this will allow using the hardware debugger to see where      */ +	/* it traps, and with what register values etc.                  */ +	// b	$ + +	mtsprg	0,r0 +	mfctr	r0 +	mtsprg  2,r0 +	mflr	r0 +// 10 +	mtsprg  3,r0 +	ld	r0, (\i + 0x60)(0) +	mtctr	r0 +	li	r0, \i + 0x100 +// 20 +	bctr + +	. = \i + 0x60 +	.quad	intHandler2C +	.endr + +	. = XVECT_M_HANDLER - 0x100 +	.quad	0x00 +	.text + +	/* Here's the startup code for the master CPU */ +	.org 0x4000 - 0x100 +_start: +	/* Save device-tree pointer */ +	mr	r31,r3 + +	/* Switch to 64-bit mode with 64-bit exceptions */ +#define MSR_SF_LG	63              /* Enable 64 bit mode */ +#define MSR_ISF_LG	61              /* Interrupt 64b mode valid on 630 */ +#define __MASK(X)	(1<<(X)) +#define MSR_SF		__MASK(MSR_SF_LG)	/* Enable 64 bit mode */ +#define MSR_ISF		__MASK(MSR_ISF_LG)	/* Interrupt 64b mode */ +	mfmsr	r11			/* grab the current MSR */ +	li	r12,(MSR_SF | MSR_ISF)@highest +	sldi	r12,r12,48 +	or	r11,r11,r12 +	mtmsrd	r11 +	isync + +	/* Early greet */ +	li	r3,10 +	bl	putc +	li	r3,13 +	bl	putc +	li	r3,10 +	bl	putc +	li	r3,'S' +	bl	putc + +	li	r3,'L' +	bl	putc +	li	r3,'O' +	bl	putc +	li	r3,'F' +	bl	putc + +	bl	print_version + +	/* go! */ +	li	r3,__startC@l +	mtctr	r3 +	bctrl +	 +	/* write a character to the HV console */ +putc:	sldi	r6,r3,(24+32) +	li	r3,0x58 +	li	r4,0 +	li	r5,1 +	.long	0x44000022 +	blr + +relTag: +	.ascii  RELEASE +	.ascii	"\0" +	.align	2 + +C_ENTRY(proceedInterrupt) + +	ld      r3,exception_stack_frame@got(r2) +	ld	r1,0(r3) + +	.irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \ +	        17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \ +		27, 28, 29, 30, 31 +	ld	r\i, 0x30+\i*8 (r1) +	.endr + +	ld	r14,0x138(r1); +	mtsrr0	r14 + +	ld	r14,0x140(r1); +	mtsrr1	r14 + +	ld	r14,0x148(r1); +	mtcr	r14 + +	ld	0,XVECT_M_HANDLER(0) +	mtctr	0 + +	ld	r0,0x30(r1); # restore vector number +	ld	r1,0x38(r1); + +	bctr + +intHandler2C: +	mtctr	r1 # save old stack pointer +	lis	r1,0x4 +	stdu	r1, -0x160(r1) +	.irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \ +	        17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \ +		27, 28, 29, 30, 31 +	std	r\i, 0x30+\i*8 (r1) +	.endr + +	std	r0,0x30(r1);  # save vector number + +	mfctr	r14 +	std	r14,0x38(r1); # save old r1 + +	mfsrr0	r14 +	std	r14,0x138(r1); + +	mfsrr1	r14 +	std	r14,0x140(r1); + +	mfcr	r14 +	std	r14,0x148(r1); + +	mfxer	r14 +	std	r14,0x150(r1); + +	bl	toc_init + +	ld      r3,exception_stack_frame@got(r2) +	std     r1,0(r3) + + +	mr 	r3,r0 +	bl	.c_interrupt + +	ld	r14,0x138(r1); +	mtsrr0	r14 + +	ld	r14,0x140(r1); +	mtsrr1	r14 + +	ld	r14,0x148(r1); +	mtcr	r14 + +	ld	r14,0x150(r1); +	mtxer	r14 + + +	.irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \ +	        17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \ +		27, 28, 29, 30, 31 +	ld	r\i, 0x30+\i*8 (r1) +	.endr + +	ld	r1,0x38(r1); + +	mfsprg	r0,2 +	mtctr	r0 +	mfsprg	r0,3 +	mtlr	r0 +	mfsprg	r0,0 +	rfid + +/* Set exception handler for given exception vector.   +	r3:	exception vector offset +	r4:	exception handler +*/ +	.globl .set_exception +.set_exception: +	.globl set_exception +set_exception: +	ld r4,0x0(r4) +	.globl .set_exception_asm +.set_exception_asm: +	.globl set_exception_asm +set_exception_asm: +	std	r4, 0x60(r3)	# fixme diff 1f - 0b +	blr diff --git a/roms/SLOF/board-qemu/llfw/version.S b/roms/SLOF/board-qemu/llfw/version.S new file mode 100644 index 00000000..f0a778ab --- /dev/null +++ b/roms/SLOF/board-qemu/llfw/version.S @@ -0,0 +1,42 @@ +/****************************************************************************** + * Copyright (c) 2010, 2011 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +/* + * Print version information + * This code is in a separate file so that it can be easily compiled during + * each new build (for refreshing the build date). + */ + +#include "termctrl.h" +#include <product.h> + +.global print_version +print_version: +	mflr	r4 +	bl	0f +	.ascii	TERM_CTRL_RESET +	.ascii	TERM_CTRL_CRSOFF +	.ascii  " **********************************************************************" +	.ascii	"\r\n" +	.ascii	TERM_CTRL_BRIGHT +	.ascii	PRODUCT_NAME +	.ascii  " Starting\r\n" +	.ascii  TERM_CTRL_RESET +	.ascii  " Build Date = ", __DATE__, " ", __TIME__ +	.ascii	"\r\n" +	.ascii  " FW Version = " , RELEASE +	.ascii	"\r\n\0" +	.align	2 +0: +	mflr	r3 +	mtlr	r4 +	b	io_print diff --git a/roms/SLOF/board-qemu/romfs/boot_rom.ffs b/roms/SLOF/board-qemu/romfs/boot_rom.ffs new file mode 100644 index 00000000..3cdb7d34 --- /dev/null +++ b/roms/SLOF/board-qemu/romfs/boot_rom.ffs @@ -0,0 +1,20 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2011 IBM Corporation +# * All rights reserved. +# * This program and the accompanying materials +# * are made available under the terms of the BSD License +# * which accompanies this distribution, and is available at +# * http://www.opensource.org/licenses/bsd-license.php +# * +# * Contributors: +# *     IBM Corporation - initial implementation +# ****************************************************************************/ + +# FFile-Name	Real Filename			Flags			ROM-Offset i/a +#--------------|-------------------------------|-----------------------|-------------- +header		romfs/header.img		0			0 +stage1		board-qemu/llfw/stage1.bin	1			0x100 +xvect		slof/xvect.bin			0			0 +ofw_main	board-qemu/slof/paflof		0			0 +bootinfo	board-qemu/llfw/Cboot.bin	0			0 +snk		clients/net-snk.client		0			0 diff --git a/roms/SLOF/board-qemu/slof/.gitignore b/roms/SLOF/board-qemu/slof/.gitignore new file mode 100644 index 00000000..55268aa6 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/.gitignore @@ -0,0 +1 @@ +OF.ffs diff --git a/roms/SLOF/board-qemu/slof/Makefile b/roms/SLOF/board-qemu/slof/Makefile new file mode 100644 index 00000000..283f77d3 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/Makefile @@ -0,0 +1,126 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2011 IBM Corporation +# * All rights reserved. +# * This program and the accompanying materials +# * are made available under the terms of the BSD License +# * which accompanies this distribution, and is available at +# * http://www.opensource.org/licenses/bsd-license.php +# * +# * Contributors: +# *     IBM Corporation - initial implementation +# ****************************************************************************/ + + +include ../Makefile.dirs + +include $(TOPBRDDIR)/config +include $(TOPCMNDIR)/make.rules + +all: version.o Makefile.dep OF.ffs paflof $(SLOFCMNDIR)/xvect.bin + +CPPFLAGS = -I$(LIBCMNDIR)/libbootmsg -I$(LIBCMNDIR)/libhvcall \ +	   -I$(LIBCMNDIR)/libvirtio -I$(LIBCMNDIR)/libnvram \ +	   -I$(LIBCMNDIR)/libusb -I$(LIBCMNDIR)/libveth \ +	   -I$(LIBCMNDIR)/libe1k +SLOF_LIBS = \ +	$(LIBCMNDIR)/libbootmsg.a \ +	$(LIBCMNDIR)/libelf.a \ +	$(LIBCMNDIR)/libhvcall.a \ +	$(LIBCMNDIR)/libvirtio.a \ +	$(LIBCMNDIR)/libusb.a \ +	$(LIBCMNDIR)/libnvram.a \ +	$(LIBCMNDIR)/libveth.a \ +	$(LIBCMNDIR)/libe1k.a +BOARD_SLOF_IN = \ +	$(LIBCMNDIR)/libhvcall/hvcall.in \ +	$(LIBCMNDIR)/libvirtio/virtio.in \ +	$(LIBCMNDIR)/libusb/usb.in \ +	$(LIBCMNDIR)/libbootmsg/bootmsg.in \ +	$(LIBCMNDIR)/libelf/libelf.in \ +	$(LIBCMNDIR)/libnvram/libnvram.in \ +	$(LIBCMNDIR)/libbases/libbases.in \ +	$(LIBCMNDIR)/libveth/veth.in \ +	$(LIBCMNDIR)/libe1k/e1k.in +BOARD_SLOF_CODE = $(BOARD_SLOF_IN:%.in=%.code) + +include $(SLOFCMNDIR)/Makefile.inc + +AS1FLAGS  = $(CPPFLAGS) $(RELEASE) $(FLAG) $(CPUARCHDEF)  -Wa,-mregnames + +%.o: %.S +	$(CC) $(AS1FLAGS) -o $@ -c $^ + +FPPINCLUDES = -I. -I$(SLOFCMNDIR)/fs -I$(SLOFCMNDIR) + +USB_FFS_FILES = \ +	$(SLOFCMNDIR)/fs/devices/pci-class_02.fs \ +	$(SLOFCMNDIR)/fs/devices/pci-class_0c.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-hci.fs \ +	$(SLOFCMNDIR)/fs/usb/slofdev.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-parent-calls.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-keyb.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-mouse.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-storage.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-hub.fs + + +VIO_FFS_FILES = \ +	$(SLOFBRDDIR)/pci-device_1af4_1000.fs \ +	$(SLOFBRDDIR)/pci-device_1af4_1001.fs \ +	$(SLOFBRDDIR)/pci-device_1af4_1004.fs \ +	$(SLOFBRDDIR)/pci-device_1af4_1009.fs \ +	$(SLOFBRDDIR)/vio-hvterm.fs \ +	$(SLOFBRDDIR)/vio-vscsi.fs \ +	$(SLOFBRDDIR)/vio-veth.fs \ +	$(SLOFBRDDIR)/rtas-nvram.fs \ +	$(SLOFBRDDIR)/virtio-net.fs \ +	$(SLOFBRDDIR)/virtio-block.fs \ +	$(SLOFBRDDIR)/virtio-fs.fs \ +	$(SLOFBRDDIR)/dev-null.fs \ +	$(SLOFBRDDIR)/virtio-scsi.fs + +# Files that should go into the ROM fs (and so have to be listed in OF.ffs): +OF_FFS_FILES = \ +	$(SLOFCMNDIR)/fs/ide.fs \ +	$(SLOFCMNDIR)/fs/fbuffer.fs \ +	$(SLOFCMNDIR)/fs/graphics.fs \ +	$(SLOFCMNDIR)/fs/generic-disk.fs \ +	$(SLOFCMNDIR)/fs/dma-function.fs \ +	$(SLOFCMNDIR)/fs/pci-device.fs \ +	$(SLOFCMNDIR)/fs/pci-bridge.fs \ +	$(SLOFCMNDIR)/fs/pci-properties.fs \ +	$(SLOFCMNDIR)/fs/pci-config-bridge.fs \ +	$(SLOFCMNDIR)/fs/update_flash.fs \ +	$(SLOFCMNDIR)/fs/xmodem.fs \ +	$(SLOFCMNDIR)/fs/scsi-disk.fs \ +	$(SLOFCMNDIR)/fs/scsi-host-helpers.fs \ +	$(SLOFCMNDIR)/fs/scsi-probe-helpers.fs \ +	$(SLOFCMNDIR)/fs/scsi-support.fs \ +	$(SLOFBRDDIR)/default-font.bin \ +	$(SLOFBRDDIR)/pci-phb.fs \ +	$(SLOFBRDDIR)/rtas.fs \ +	$(SLOFBRDDIR)/pci-device_1234_1111.fs \ +	$(SLOFBRDDIR)/pci-device_1013_00b8.fs \ +	$(SLOFBRDDIR)/pci-device_8086_100e.fs \ +	$(SLOFBRDDIR)/e1k.fs \ +	$(FCODE_FFS_FILES) + +# Uncomment the following line to enable the USB code: +OF_FFS_FILES += $(USB_FFS_FILES) + +OF_FFS_FILES += $(VIO_FFS_FILES) + +OF_FFS_FILES := $(OF_FFS_FILES:%.fs=%.fsi) + +OF.ffs: Makefile $(SLOFCMNDIR)/Makefile.inc $(OF_FFS_FILES) +	$(MAKE) create_OF_ffs + +# Rules for cleaning up: +.PHONY: clean_here clean distclean + +clean_here: +	rm -f *.o OF.fsi OF.ffs + +clean: clean_here clean_slof + +distclean: clean_here distclean_slof diff --git a/roms/SLOF/board-qemu/slof/OF.fs b/roms/SLOF/board-qemu/slof/OF.fs new file mode 100644 index 00000000..561d8922 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/OF.fs @@ -0,0 +1,306 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ The master file.  Everything else is included into here. + +hex + +' ll-cr to cr + +#include "header.fs" + +#include "hvterm.fs" + +#include "base.fs" + +\ Set default load-base to 0x4000 +4000 to default-load-base + +\ Little-endian accesses.  Also known as `wrong-endian'. +#include <little-endian.fs> + +: #join  ( lo hi #bits -- x )  lshift or ; +: #split ( x #bits -- lo hi )  2dup rshift dup >r swap lshift xor r> ; + +: blink ; +: reset-dual-emit ; +: console-clean-fifo ; +: bootmsg-nvupdate ; +: asm-cout 2drop drop ; + +#include "logging.fs" + +: log-string 2drop ; + +#include "bootmsg.fs" + +000 cp + +#include "exception.fs" + +: mm-log-warning 2drop ; + +: write-mm-log ( data length type -- status ) +	3drop 0 +; + +100 cp + +\ Input line editing. +#include "accept.fs" + +120 cp + +#include "dump.fs" + +cistack ciregs >r1 ! \ kernel wants a stack :-) + +140 cp + +#include "romfs.fs" + +200 cp + +#include <slof-logo.fs> + +201 cp + +#include <banner.fs> + +: .banner .slof-logo .banner ; + +220 cp + +DEFER find-boot-sector ( -- ) + +240 cp +\ Timebase frequency, in Hz. Start with a good default +\ Use device-tree later to fix it up +d# 512000000 VALUE tb-frequency   \ default value - needed for "ms" to work +-1 VALUE cpu-frequency + +#include "helper.fs" +260 cp + +#include <timebase.fs> + +270 cp + +#include <fcode/evaluator.fs> + +2e0 cp + +#include <quiesce.fs> + +300 cp + +#include <usb/usb-static.fs> + +320 cp + +#include <scsi-loader.fs> + +340 cp + +#include "fdt.fs" + +360 cp + +#include <root.fs> + +370 cp + +: check-boot-menu +   s" qemu,boot-menu" get-chosen IF +      decode-int 1 = IF +         ." Press F12 for boot menu." cr cr +      THEN +      2drop +   THEN +; +check-boot-menu + +380 cp + +\ Grab rtas from qemu +#include "rtas.fs" + +390 cp + +#include "virtio.fs" + +3f0 cp + +#include "tree.fs" + +800 cp + +#include "nvram.fs" + +880 cp + +#include "envvar.fs" +check-for-nvramrc + +890 cp + +#include "qemu-bootlist.fs" + +8a0 cp + +\ The client interface. +#include "client.fs" +\ ELF binary file format. +#include "elf.fs" +#include <loaders.fs> + +8a8 cp +CREATE version-str 10 ALLOT +0 value temp-ptr + +: dump-display-buffer +    disp-ptr to temp-ptr +    " SLOF **********************************************************************" terminal-write drop +    cr +    version-str get-print-version +    version-str @                   \ start +    version-str 8 + @               \ end +    over - terminal-write drop +    " Press 's' to enter Open Firmware." terminal-write drop +    cr cr +    temp-ptr disp-size > IF +	temp-ptr disp-size MOD +	dup +	prevga-disp-buf + swap disp-size swap - terminal-write drop +	temp-ptr disp-size MOD +	prevga-disp-buf swap 1 - terminal-write drop +    ELSE +	prevga-disp-buf temp-ptr terminal-write drop +    THEN +; + +: enable-framebuffer-output  ( -- ) +\ enable output on framebuffer +   s" screen" find-alias ?dup  IF +      \ we need to open/close the screen device once +      \ before "ticking" display-emit to emit +      open-dev close-node +      false to store-prevga? +      s" display-emit" $find  IF  +         to emit  +	 dump-display-buffer +      ELSE +         2drop +      THEN +   THEN +; + +enable-framebuffer-output + +8b0 cp + +\ Scan USB devices +usb-scan + +8c0 cp + +\ Claim remaining memory that is used by firmware: +romfs-base 400000 0 ' claim CATCH IF ." claim failed!" cr 2drop THEN drop + +8d0 cp + +: set-default-console +    s" linux,stdout-path" get-chosen IF +        decode-string +        ." Using default console: " 2dup type cr +        io +        2drop +    ELSE +        ." No console specified " +        " screen" find-alias dup IF nip THEN +        " keyboard" find-alias dup IF nip THEN +	AND IF +	  ." using screen & keyboard" cr +	  " screen" output +	  " keyboard" input +        ELSE +          " hvterm" find-alias IF +	    drop +	    ." using hvterm" cr +            " hvterm" io +	  ELSE +	    " /openprom" find-node ?dup IF +		set-node +		." and no default found, creating dev-null" cr +		" dev-null.fs" included +		" devnull-console" io +		0 set-node +	    THEN +	  THEN +        THEN +    THEN +; +set-default-console + +8e0 cp + +\ Check if we are booting a kernel passed by qemu, in which case +\ we skip initializing some devices + +0 VALUE direct-ram-boot-base +0 VALUE direct-ram-boot-size + +: (boot-ram) +    direct-ram-boot-size 0<> IF +        ." Booting from memory..." cr +	s" go-args 2@ " evaluate +	direct-ram-boot-base 0 +	s" true state-valid ! " evaluate +	s" disable-watchdog go-64" evaluate +    THEN +; + +8e8 cp + +: check-boot-from-ram +    s" qemu,boot-kernel" get-chosen IF +        decode-int -rot decode-int -rot ( n1 n2 p s ) +	decode-int -rot decode-int -rot ( n1 n2 n3 n4 p s ) +	2drop +	swap 20 << or to direct-ram-boot-size +	swap 20 << or to direct-ram-boot-base +	." Detected RAM kernel at " direct-ram-boot-base . +	." (" direct-ram-boot-size . ." bytes) " +	\ Override the boot-command word without touching the +	\ nvram environment +	s" boot-command" $create " (boot-ram)" env-string +    THEN +; +check-boot-from-ram + +8ff cp + +#include <start-up.fs> + +."      "   \ Clear last checkpoint + +#include <boot.fs> + +cr .(   Welcome to Open Firmware) +cr +#include "copyright-oss.fs" +cr cr + +\ this CATCH is to ensure the code bellow always executes:  boot may ABORT! +' start-it CATCH drop + +cr ." Ready!" diff --git a/roms/SLOF/board-qemu/slof/copyright-oss.fs b/roms/SLOF/board-qemu/slof/copyright-oss.fs new file mode 100644 index 00000000..e45b1940 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/copyright-oss.fs @@ -0,0 +1,16 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +cr .(   Copyright (c) char ) emit .(  2004, 2011 IBM Corporation All rights reserved.) +cr .(   This program and the accompanying materials are made available) +cr .(   under the terms of the BSD License available at) +cr .(   http://www.opensource.org/licenses/bsd-license.php) diff --git a/roms/SLOF/board-qemu/slof/dev-null.fs b/roms/SLOF/board-qemu/slof/dev-null.fs new file mode 100644 index 00000000..d0ffad6b --- /dev/null +++ b/roms/SLOF/board-qemu/slof/dev-null.fs @@ -0,0 +1,35 @@ +\ Introduce a dummy console that will eat away all chars and make all +\ the components dependent on stdout happy. + +new-device +" devnull-console" device-name + +: open true ; +: close ; + +: write ( adr len -- actual ) +  nip +; + +: read  ( adr len -- actual ) +  nip +; + +: setup-alias +    " devnull-console" find-alias 0= IF +        " devnull-console" get-node node>path set-alias +    ELSE +        drop +    THEN +; + +: dummy-term-emit drop ; +: dummy-term-key  0 ; +: dummy-term-key? FALSE ; + +' dummy-term-emit to emit +' dummy-term-key  to key +' dummy-term-key? to key? + +setup-alias +finish-device diff --git a/roms/SLOF/board-qemu/slof/e1k.fs b/roms/SLOF/board-qemu/slof/e1k.fs new file mode 100644 index 00000000..51855be8 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/e1k.fs @@ -0,0 +1,98 @@ +\ ***************************************************************************** +\ * Copyright (c) 2013 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ Handle e1000 device + +s" network" device-type + +INSTANCE VARIABLE obp-tftp-package +get-node CONSTANT my-phandle +10 config-l@ translate-my-address 3 not AND CONSTANT baseaddr + +0 VALUE e1k-priv +0 VALUE open-count + +: open  ( -- okay? ) +   open-count 0= IF +       open IF +	 baseaddr +         e1k-open dup not IF ." e1k-open failed" EXIT THEN +         drop TO e1k-priv +         true +      ELSE +         false +      THEN +   ELSE +      true +   THEN +   my-args s" obp-tftp" $open-package obp-tftp-package ! +   open-count 1 + to open-count +; + + +: close  ( -- ) +   my-phandle set-node +   open-count 0> IF +      open-count 1 - dup to open-count +      0= IF +         e1k-priv e1k-close +         close +      THEN +   THEN +   s" close" obp-tftp-package @ $call-method +; + +: read ( buf len -- actual ) +   dup IF +      e1k-read +   ELSE   +      nip +   THEN +; + +: write ( buf len -- actual ) +   dup IF +      e1k-write +   ELSE +      nip +   THEN +; + +: load  ( addr -- len ) +   s" load" obp-tftp-package @ $call-method +; + +: ping  ( -- ) +   s" ping" obp-tftp-package @ $call-method +; + +6 BUFFER: local-mac +: setup-mac ( -- ) +   pci-mem-enable +   " vendor-id" get-node get-property IF EXIT THEN +   decode-int nip nip +   " device-id" get-node get-property IF EXIT THEN +   decode-int nip nip +   baseaddr +   local-mac e1k-mac-setup IF +      encode-bytes  " local-mac-address"  property +   THEN +; + +setup-mac + +: setup-alias  ( -- ) +   " net" get-next-alias ?dup IF +      get-node node>path set-alias +   THEN +; +setup-alias diff --git a/roms/SLOF/board-qemu/slof/fdt.fs b/roms/SLOF/board-qemu/slof/fdt.fs new file mode 100644 index 00000000..8d4635f3 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/fdt.fs @@ -0,0 +1,435 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +0 VALUE fdt-debug +TRUE VALUE fdt-cas-fix? + +\ Bail out if no fdt +fdt-start 0 = IF -1 throw THEN + +struct +  4 field >fdth_magic +  4 field >fdth_tsize +  4 field >fdth_struct_off +  4 field >fdth_string_off +  4 field >fdth_rsvmap_off +  4 field >fdth_version +  4 field >fdth_compat_vers +  4 field >fdth_boot_cpu +  4 field >fdth_string_size +  4 field >fdth_struct_size +drop + +h# d00dfeed constant OF_DT_HEADER +h#        1 constant OF_DT_BEGIN_NODE +h#        2 constant OF_DT_END_NODE +h#        3 constant OF_DT_PROP +h#        4 constant OF_DT_NOP +h#        9 constant OF_DT_END + +\ Create some variables early +0 value fdt-start-addr +0 value fdt-struct +0 value fdt-strings + +: fdt-init ( fdt-start -- ) +    dup to fdt-start-addr +    dup dup >fdth_struct_off l@ + to fdt-struct +    dup dup >fdth_string_off l@ + to fdt-strings +    drop +; +fdt-start fdt-init + +\ Dump fdt header for all to see and check FDT validity +: fdt-check-header ( -- ) +    fdt-start-addr dup 0 = IF +        ." No flat device tree !" cr drop -1 throw EXIT THEN +    hex +    fdt-debug IF +        ." Flat device tree header at 0x" dup . s" :" type cr +        ."  magic            : 0x" dup >fdth_magic l@ . cr +        ."  total size       : 0x" dup >fdth_tsize l@ . cr +        ."  offset to struct : 0x" dup >fdth_struct_off l@ . cr +        ."  offset to strings: 0x" dup >fdth_string_off l@ . cr +        ."  offset to rsvmap : 0x" dup >fdth_rsvmap_off l@ . cr +        ."  version          : " dup >fdth_version l@ decimal . hex cr +        ."  last compat vers : " dup >fdth_compat_vers l@ decimal . hex cr +        dup >fdth_version l@ 2 >= IF +            ."  boot CPU         : 0x" dup >fdth_boot_cpu l@ . cr +        THEN +        dup >fdth_version l@ 3 >= IF +            ."  strings size     : 0x" dup >fdth_string_size l@ . cr +        THEN +        dup >fdth_version l@ 17 >= IF +            ."  struct size      : 0x" dup >fdth_struct_size l@ . cr +        THEN +    THEN +    dup >fdth_magic l@ OF_DT_HEADER <> IF +        ." Flat device tree has incorrect magic value !" cr +	drop -1 throw EXIT +    THEN +    dup >fdth_version l@ 10 < IF +        ." Flat device tree has usupported version !" cr +	drop -1 throw EXIT +    THEN + +    drop +; +fdt-check-header + +\ Fetch next tag, skip nops and increment address +: fdt-next-tag ( addr -- nextaddr tag ) +  0	       	      	 	( dummy tag on stack for loop ) +  BEGIN +    drop			( drop previous tag ) +    dup l@			( read new tag ) +    swap 4 + swap		( increment addr ) +  dup OF_DT_NOP <> UNTIL 	( loop until not nop ) +; + +\ Parse unit name and advance addr +: fdt-fetch-unit ( addr -- addr $name ) +  dup from-cstring	       \  get string size +  2dup + 1 + 3 + fffffffc and -rot +; + +\ Update unit with information from the reg property... +\ ... this is required for the PCI nodes for example. +: fdt-reg-unit ( prop-addr prop-len -- ) +      decode-phys               ( prop-addr' prop-len' phys.lo ... phys.hi ) +      set-unit                  ( prop-addr' prop-len' ) +      2drop +; + +\ Lookup a string by index +: fdt-fetch-string ( index -- str-addr str-len )   +  fdt-strings + dup from-cstring +; + +: fdt-create-dec  s" decode-unit" $CREATE , DOES> @ hex64-decode-unit ; +: fdt-create-enc  s" encode-unit" $CREATE , DOES> @ hex64-encode-unit ; + +\ Check whether array contains an zero-terminated ASCII string: +: fdt-prop-is-string?  ( addr len -- string? ) +   dup 1 < IF 2drop FALSE EXIT THEN                \ Check for valid length +   1- +   2dup + c@ 0<> IF 2drop FALSE EXIT THEN          \ Check zero-termination +   test-string +; + +\ Encode fdt property to OF property +: fdt-encode-prop  ( addr len -- ) +   2dup fdt-prop-is-string? IF +      1- encode-string +   ELSE +      encode-bytes +   THEN +; + +\ Method to unflatten a node +: fdt-unflatten-node ( start -- end ) +  \ this can and will recurse +  recursive + +  \ Get & check first tag of node ( addr -- addr) +  fdt-next-tag dup OF_DT_BEGIN_NODE <> IF +    s" Weird tag 0x" type . " at start of node" type cr +    -1 throw +  THEN drop + +  new-device + +  \ Parse name, split unit address +  fdt-fetch-unit +  dup 0 = IF drop drop " /" THEN +  40 left-parse-string +  \ Set name +  device-name + +  \ Set preliminary unit address - might get overwritten by reg property +  dup IF +     " #address-cells" get-parent get-package-property IF +        2drop +     ELSE +        decode-int nip nip +	hex-decode-unit +	set-unit +     THEN +  ELSE 2drop THEN + +  \ Iterate sub tags +  BEGIN +    fdt-next-tag dup OF_DT_END_NODE <> +  WHILE +    dup OF_DT_PROP = IF +      \ Found property +      drop dup			( drop tag, dup addr     : a1 a1 ) +      dup l@ dup rot 4 +	( fetch size, stack is   : a1 s s a2) +      dup l@ swap 4 +		( fetch nameid, stack is : a1 s s i a3 ) +      rot			( we now have: a1 s i a3 s ) +      fdt-encode-prop rot	( a1 s pa ps i) +      fdt-fetch-string		( a1 s pa ps na ns ) +      2dup s" reg" str= IF +          2swap 2dup fdt-reg-unit 2swap +      THEN +      property +      + 8 + 3 + fffffffc and +    ELSE dup OF_DT_BEGIN_NODE = IF +      drop			( drop tag ) +      4 - +      fdt-unflatten-node +    ELSE +      drop -1 throw +    THEN THEN +  REPEAT drop \ drop tag + +  \ Create encode/decode unit +  " #address-cells" get-node get-package-property IF ELSE +    decode-int dup fdt-create-dec fdt-create-enc 2drop +  THEN + +  finish-device   +; + +\ Start unflattening +: fdt-unflatten-tree +    fdt-debug IF +        ." Unflattening device tree..." cr THEN +    fdt-struct fdt-unflatten-node drop +    fdt-debug IF +        ." Done !" cr THEN +; +fdt-unflatten-tree + +\ Find memory size +: fdt-parse-memory +    \ XXX FIXME Handle more than one memory node, and deal +    \     with RMA vs. full access +    " /memory@0" find-device +    " reg" get-node get-package-property IF throw -1 THEN + +    \ XXX FIXME Assume one entry only in "reg" property for now +    decode-phys 2drop decode-phys +    my-#address-cells 1 > IF 20 << or THEN +     +    fdt-debug IF +        dup ." Memory size: " . cr +    THEN +    \ claim.fs already released the memory between 0 and MIN-RAM-SIZE, +    \ so we've got only to release the remaining memory now: +    MIN-RAM-SIZE swap MIN-RAM-SIZE - release +    2drop device-end +; +fdt-parse-memory + + +\ Claim fdt memory and reserve map +: fdt-claim-reserve +    fdt-start-addr +    dup dup >fdth_tsize l@ 0 claim drop +    dup >fdth_rsvmap_off l@ + +    BEGIN +        dup dup x@ swap 8 + x@ +	dup 0 <> +    WHILE +	fdt-debug IF +	    2dup swap ." Reserve map entry: " . ." : " . cr +	THEN +	0 claim drop +	10 + +    REPEAT drop drop drop +; +fdt-claim-reserve  + + +\ The following functions are use to replace the FDT phandle and +\ linux,phandle properties with our own OF1275 phandles... + +\ This is used to check whether we successfully replaced a phandle value +0 VALUE (fdt-phandle-replaced) + +\ Replace phandle value in "interrupt-map" property +: fdt-replace-interrupt-map  ( old new prop-addr prop-len -- old new ) +   BEGIN +      dup                    ( old new prop-addr prop-len prop-len ) +   WHILE +      \ This is a little bit ugly ... we're accessing the property at +      \ hard-coded offsets instead of analyzing it completely... +      swap dup 10 +          ( old new prop-len prop-addr prop-addr+10 ) +      dup l@ 5 pick = IF +          \ it matches the old phandle value! +          3 pick swap l! +          TRUE TO (fdt-phandle-replaced) +      ELSE +          drop +      THEN +      ( old new prop-len prop-addr ) +      1c + swap 1c - +      ( old new new-prop-addr new-prop-len ) +   REPEAT +   2drop +; + +\ Replace one FDT phandle "old" with a OF1275 phandle "new" in the +\ whole tree: +: fdt-replace-all-phandles ( old new node -- ) +   \ ." Replacing in " dup node>path type cr +   >r +   s" interrupt-map" r@ get-property 0= IF +      ( old new prop-addr prop-len  R: node ) +      fdt-replace-interrupt-map +   THEN +   s" interrupt-parent" r@ get-property 0= IF +      ( old new prop-addr prop-len  R: node ) +      decode-int -rot 2drop                  ( old new val  R: node ) +      2 pick = IF                            ( old new      R: node ) +         dup encode-int s" interrupt-parent" r@ set-property +         TRUE TO (fdt-phandle-replaced) +      THEN +   THEN +   \ ... add more properties that have to be fixed here ... +   r> +   \ Now recurse over all child nodes:       ( old new node ) +   child BEGIN +      dup +   WHILE +      3dup RECURSE +      PEER +   REPEAT +   3drop +; + +\ Check whether a node has "phandle" or "linux,phandle" properties +\ and replace them: +: fdt-fix-node-phandle  ( node -- ) +   >r +   FALSE TO (fdt-phandle-replaced) +   s" phandle" r@ get-property 0= IF +      decode-int                       ( p-addr2 p-len2 val ) +      \ ." found phandle: " dup . cr +      r@ s" /" find-node               ( p-addr2 p-len2 val node root )   +      fdt-replace-all-phandles         ( p-addr2 p-len2 ) +      2drop +      (fdt-phandle-replaced) IF +         r@ set-node +         s" phandle" delete-property +         s" linux,phandle" delete-property +      ELSE +         diagnostic-mode? IF +            cr ." Warning: Did not replace phandle in " r@ node>path type cr +         THEN +      THEN +   THEN +   r> drop +; + +\ Recursively walk through all nodes to fix their phandles: +: fdt-fix-phandles  ( node -- ) +   \ ." fixing phandles of " dup node>path type cr +   dup fdt-fix-node-phandle +   child BEGIN +      dup +   WHILE +      dup RECURSE +      PEER +   REPEAT +   drop +   device-end +; + +: fdt-create-cas-node ( name  -- ) +    2dup +    2dup " memory@" find-substr 0 = IF +	fdt-debug IF ." Creating memory@ " cr THEN +	new-device +	2dup " @" find-substr nip device-name       \ Parse the node name +	2dup +	2dup " @" find-substr rot over + 1 + -rot - 1 - \ Jump to addr afte "@" +	parse-2int nip xlsplit set-unit                 \ Parse and set unit +	finish-device +    ELSE +	2dup " ibm,dynamic-reconfiguration-memory" find-substr 0 = IF +	    fdt-debug IF  ." Creating ibm,dynamic-reconfiguration-memory " cr THEN +	    new-device +	    device-name +	    finish-device +	ELSE +	    2drop 2drop +	    false to fdt-cas-fix? +	    ." Node not supported " cr +	    EXIT +	THEN +    THEN + +    find-node ?dup 0 <> IF set-node THEN +; + +: fdt-fix-cas-node ( start -- end ) +    recursive +    fdt-next-tag dup OF_DT_BEGIN_NODE <> IF +	." Error " cr +	false to fdt-cas-fix? +	EXIT +    THEN drop +    fdt-fetch-unit +    dup 0 = IF drop drop " /" THEN +    40 left-parse-string +    2swap ?dup 0 <> IF +	nip +	1 + + \ Add the string len +@ +    ELSE +	drop +    THEN +    fdt-debug IF ." Setting node: " 2dup type cr THEN +    2dup find-node ?dup 0 <> IF +	set-node 2drop +    ELSE +	fdt-debug IF ." Node not found, creating " 2dup type cr THEN +	fdt-create-cas-node +    THEN +    fdt-debug IF ." Current  now: " pwd cr THEN +    BEGIN +	fdt-next-tag dup OF_DT_END_NODE <> +    WHILE +	dup OF_DT_PROP = IF +	    fdt-debug IF ." Found property " cr THEN +	    drop dup		( drop tag, dup addr     : a1 a1 ) +	    dup l@ dup rot 4 +	( fetch size, stack is   : a1 s s a2) +	    dup l@ swap 4 +	( fetch nameid, stack is : a1 s s i a3 ) +	    rot			( we now have: a1 s i a3 s ) +	    fdt-encode-prop rot	( a1 s pa ps i) +	    fdt-fetch-string		( a1 s pa ps na ns ) +	    property +	    fdt-debug IF ." Setting property done " cr THEN +	    + 8 + 3 + fffffffc and +	ELSE dup OF_DT_BEGIN_NODE = IF +		drop			( drop tag ) +		4 - +		fdt-fix-cas-node +		get-parent set-node +		fdt-debug IF ." Returning back " pwd cr THEN +	    ELSE +		." Error " cr +		drop +		false to fdt-cas-fix? +		EXIT +	    THEN +	THEN +    REPEAT +    drop \ drop tag +; + +: fdt-fix-cas-success +    fdt-cas-fix? +; + +s" /" find-node fdt-fix-phandles diff --git a/roms/SLOF/board-qemu/slof/header.fs b/roms/SLOF/board-qemu/slof/header.fs new file mode 100644 index 00000000..8bc17a18 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/header.fs @@ -0,0 +1,18 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ XXXFIXME: Old Bimini/JX2x crap to remove + +get-flash-base VALUE flash-addr + +get-nvram-base CONSTANT nvram-base +get-nvram-size CONSTANT nvram-size diff --git a/roms/SLOF/board-qemu/slof/helper.fs b/roms/SLOF/board-qemu/slof/helper.fs new file mode 100644 index 00000000..96da4989 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/helper.fs @@ -0,0 +1,35 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +: slof-build-id  ( -- str len ) +   flash-header 10 + a +; + +: slof-revision s" 001" ; + +: read-version-and-date +   flash-header 0= IF +   s"  " encode-string +   ELSE +   flash-header 10 + 10 +   here swap rmove +   here 10 +   s" , " $cat +   bdate2human $cat encode-string THEN +; + +\ Fetch C string +: from-cstring ( addr - len )   +  dup dup BEGIN c@ 0 <> WHILE 1 + dup REPEAT +  swap - +; + diff --git a/roms/SLOF/board-qemu/slof/hvterm.fs b/roms/SLOF/board-qemu/slof/hvterm.fs new file mode 100644 index 00000000..98c14458 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/hvterm.fs @@ -0,0 +1,43 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ PAPR hvterm console.  Enabled very early. + +0 CONSTANT default-hvtermno +\ Buffer for pre-display +4096 CONSTANT disp-size +CREATE prevga-disp-buf 4096 allot +0 value disp-ptr +true value store-prevga? + +: store-to-disp-buffer         ( ch  --  ) +    prevga-disp-buf disp-ptr disp-size MOD + c! +    disp-ptr 1 + to disp-ptr +; + +: hvterm-emit +    store-prevga? IF +	dup store-to-disp-buffer +    THEN +    default-hvtermno SWAP hv-putchar +; +: hvterm-key?  default-hvtermno hv-haschar ; +: hvterm-key   BEGIN hvterm-key? UNTIL default-hvtermno hv-getchar ; + +' hvterm-emit to emit +' hvterm-key  to key +' hvterm-key? to key? + +\ Override serial methods to make term-io.fs happy +: serial-emit hvterm-emit ; +: serial-key? hvterm-key? ; +: serial-key  hvterm-key  ; diff --git a/roms/SLOF/board-qemu/slof/pci-aliases.fs b/roms/SLOF/board-qemu/slof/pci-aliases.fs new file mode 100644 index 00000000..9ce519da --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-aliases.fs @@ -0,0 +1,58 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ Starting alias number for net devices after the onboard devices. +0 VALUE pci-net-num +\ Starting alias number for disks after the onboard devices. +0 VALUE pci-disk-num +\ Starting alias number for cdroms after the onboard devices. +0 VALUE pci-cdrom-num + +\ define a new alias for this device +: pci-set-alias ( str-addr str-len num -- ) +        $cathex strdup       \ create alias name +        get-node node>path   \ get path string +        set-alias            \ and set the alias +; + +\ define a new net alias +: unknown-enet ( -- pci-net-num ) +	pci-net-num dup 1+ TO pci-net-num +; +: pci-alias-net ( config-addr -- ) +        drop                                   \ forget the config address +        pci-net-num dup 1+ TO pci-net-num      \ increase the pci-net-num +        s" net" rot pci-set-alias              \ create the alias +; + +\ define a new disk alias +: pci-alias-disk ( config-addr -- ) +        drop                                    \ forget the config address +        pci-disk-num dup 1+ TO pci-disk-num     \ increase the pci-disk-num +        s" disk" rot pci-set-alias              \ create the alias +; +\ define a new cdrom alias +: pci-alias-cdrom ( config-addr -- ) +        drop                                    \ forget the config address +        pci-cdrom-num dup 1+ TO pci-cdrom-num     \ increase the pci-cdrom-num +        s" cdrom" rot pci-set-alias              \ create the alias +; + +\ define the alias for the calling device +: pci-alias ( config-addr -- ) +        dup pci-class@  +        10 rshift CASE +                01 OF   pci-alias-disk ENDOF +                02 OF   pci-alias-net  ENDOF +               dup OF   drop           ENDOF +        ENDCASE +; diff --git a/roms/SLOF/board-qemu/slof/pci-capabilities.fs b/roms/SLOF/board-qemu/slof/pci-capabilities.fs new file mode 100644 index 00000000..ef8c7b0d --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-capabilities.fs @@ -0,0 +1,34 @@ +\ Set up all known capabilities for this board to the plugged devices + +: pci-msi-prop ( addr -- ) +    5 pci-cap-find          ( capaddr ) +    ?dup IF +        2+ rtas-config-w@   ( msi-control ) +        1 rshift 7 and      ( msi-control:3:1 ) + +        dup 6 < IF +            1 swap lshift   ( vectors# ) +            encode-int " ibm,req#msi" property +        ELSE +            ." Invalid MSI vectors number " . cr +        THEN +    THEN +; + +: pci-msix-prop ( addr -- ) +    11 pci-cap-find         ( capaddr ) +    ?dup IF +        2+ rtas-config-w@   ( msix-control ) +        7ff and             ( msix-control:10:0 ) +        1+                  ( vectors# ) +        ?dup IF +            encode-int " ibm,req#msi-x" property +        THEN +    THEN +; + +: pci-set-capabilities ( config-addr -- ) +    dup pci-msi-prop +    dup pci-msix-prop +    drop +; diff --git a/roms/SLOF/board-qemu/slof/pci-device_1013_00b8.fs b/roms/SLOF/board-qemu/slof/pci-device_1013_00b8.fs new file mode 100644 index 00000000..c3ac2ec4 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1013_00b8.fs @@ -0,0 +1,265 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +my-space pci-device-generic-setup + +\ Defaults, overriden from qemu +d# 800 VALUE disp-width +d# 600 VALUE disp-height +d#   8 VALUE disp-depth + +\ Determine base address +10 config-l@ translate-my-address f not AND  VALUE fb-base + +\ Fixed up later +-1 VALUE io-base + +\ We support only one instance +false VALUE is-installed? + +: vga-io-xlate ( port -- addr ) +  io-base -1 = IF +    dup translate-my-address fff not and to io-base +  THEN +  io-base + +; + +: vga-w! ( value port -- ) +  vga-io-xlate rw!-le +; + +: vga-w@ ( port -- value ) +  vga-io-xlate rw@-le +; + +: vga-b! ( value port -- ) +  vga-io-xlate rb! +; + +: vga-b@ ( port -- value ) +  vga-io-xlate rb@ +; + +: vga-crt@ ( index -- value ) +  3d4 vga-b! +  3d5 vga-b@ +; + +: vga-crt! ( value index -- ) +  3d4 vga-b! +  3d5 vga-b! +; + +: vga-seq@ ( index -- value ) +  3c4 vga-b! +  3c5 vga-b@ +; + +: vga-seq! ( value index -- ) +  3c4 vga-b! +  3c5 vga-b! +; + +: vga-att@ ( index -- value ) +  3c0 vga-b! +  3c1 vga-b@ +; + +: vga-att! ( value index -- ) +  3c0 vga-b! +  3c0 vga-b! +; + +: vga-gfx@ ( index -- value ) +  3ce vga-b! +  3cf vga-b@ +; + +: vga-gfx! ( value index -- ) +  3ce vga-b! +  3cf vga-b! +; + +: color! ( r g b number -- )  +   3c8 vga-b! +   rot 2 >> 3c9 vga-b! +   swap 2 >> 3c9 vga-b! +   2 >> 3c9 vga-b! +; + +: color@ ( number -- r g b )  +   3c8 vga-b! +   3c9 vga-b@ 2 << +   3c9 vga-b@ 2 << +   3c9 vga-b@ 2 << +; + +: set-colors ( adr number #numbers -- ) +   over 3c8 vga-b! +   swap DO +     rb@ 2 >> 3c9 vga-b! +     rb@ 2 >> 3c9 vga-b! +     rb@ 2 >> 3c9 vga-b! +   LOOP +   3drop +; + +: get-colors ( adr number #numbers -- ) +   3drop +; + +include graphics.fs + +: init-mode +  3da vga-b@ drop \ reset flip flop +  0f 3c2 vga-b!   \ color mode, ram enable, ... +  12 06 vga-seq!  \ unlock extensions +  05 06 vga-gfx!  \ graphic mode   +  \ set bit depth. Note: we should set the hidden +  \ dac register to differenciate 15 and 16bpp, but +  \ it's annoying and in practice we don't care as +  \ we are only displaying in black & white atm +  disp-depth CASE \ set depth +     8 OF 01 07 vga-seq! ENDOF +     f OF 07 07 vga-seq! ENDOF +    10 OF 07 07 vga-seq! ENDOF +    20 OF 09 07 vga-seq! ENDOF +  ENDCASE +  ff 02 vga-seq!  \ enable plane write +  0a 04 vga-seq!  \ memory mode +  03 17 vga-crt!  \ disable display +  \ calculate line offset & split +  disp-width disp-depth 7 + 8 / * 3 >> +  dup ff and 13 vga-crt!  \ bottom bits +  4 >> 10 and 1b vga-crt! \ top bit +  disp-width 3 >> 1 -                  01 vga-crt! \ H_DISP +  disp-height 1 - ff and               12 vga-crt! \ V_DISP +  disp-height 1 - 7 >> 2 and +  disp-height 1 - 3 >> 40 and +  or 10 or                             07 vga-crt! \ OFLOW +  ff 18 vga-crt! \ LINE_COMPARE +  40 09 vga-crt! \ MAX_SCAN +  08 04 vga-crt! \ SYNC_START +  0f 02 vga-crt! \ BLANK_START +  00 0c vga-crt! +  00 0d vga-crt! +  40 05 vga-gfx! \ gfx mode +  83 17 vga-crt! \ enable display +  33 3c0 vga-b!  \ gfx in ar index +  00 3c0 vga-b! +  01 01 vga-seq! \ enable seq +; + +: clear-screen +  fb-base disp-width disp-height disp-depth 7 + 8 / * * 0 rfill +; + +: read-settings +  s" qemu,graphic-width" get-chosen IF +     decode-int to disp-width 2drop +  THEN +  s" qemu,graphic-height" get-chosen IF +     decode-int to disp-height 2drop +  THEN +  s" qemu,graphic-depth" get-chosen IF +     decode-int nip nip      +       dup 8 = +       over f = or +       over 10 = or +       over 20 = or IF +         to disp-depth +       ELSE +         ." Unsupported bit depth, using 8bpp " drop cr +       THEN +  THEN +; + +: add-legacy-reg +  \ add legacy I/O Ports / Memory regions to assigned-addresses +  \ see PCI Bus Binding Revision 2.1 Section 7. +  s" reg" get-node get-property IF +    \ "reg" does not exist, create new +    encode-start +  ELSE +    \ "reg" does exist, copy it  +    encode-bytes +  THEN +  \ I/O Range 0x1ce-0x1d2 +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  1ce encode-64+ 4 encode-64+ \ addr size +  \ I/O Range 0x3B0-0x3BB +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  3b0 encode-64+ c encode-64+ \ addr size +  \ I/O Range 0x3C0-0x3DF +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  3c0 encode-64+ 20 encode-64+ \ addr size +  \ Memory Range 0xA0000-0xBFFFF +  my-space a2000000 or encode-int+ \ non-relocatable, <1MB Memory space +  a0000 encode-64+ 20000 encode-64+ \ addr size +  s" reg" property \ store "reg" property +; + +: setup-properties +   \ Shouldn't this be done from open ? +   disp-width encode-int s" width" property +   disp-height encode-int s" height" property +   disp-width disp-depth 7 + 8 / * encode-int s" linebytes" property +   disp-depth encode-int s" depth" property +   s" ISO8859-1" encode-string s" character-set" property \ i hope this is ok... +   \ add "device_type" property +   s" display" device-type +   \ XXX We don't create an "address" property because Linux doesn't know what +   \ to do with it for >32-bit +; + +\ words for installation/removal, needed by is-install/is-remove, see display.fs +: display-remove ( -- )  +; + +: display-install ( -- ) +    is-installed? NOT IF +        ." Installing QEMU fb" cr +        fb-base to frame-buffer-adr +        default-font  +        set-font +        disp-width disp-height +        disp-width char-width / disp-height char-height / +        disp-depth 7 + 8 /                      ( width height #lines #cols depth ) +        fb-install +        true to is-installed? +    THEN +; + +: set-alias +    s" screen" find-alias 0= IF +      \ no previous screen alias defined, define it... +      s" screen" get-node node>path set-alias +    ELSE +       drop +    THEN  +; + + +." cirrus vga" cr + +pci-master-enable +pci-mem-enable +pci-io-enable +add-legacy-reg +read-settings +init-mode +clear-screen +init-default-palette +setup-properties +' display-install is-install +' display-remove is-remove +set-alias diff --git a/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs b/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs new file mode 100644 index 00000000..a5c3584f --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs @@ -0,0 +1,242 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +my-space pci-device-generic-setup + +\ Defaults, overriden from qemu +d# 800 VALUE disp-width +d# 600 VALUE disp-height +d#   8 VALUE disp-depth + +\ Determine base address +10 config-l@ translate-my-address f not AND VALUE fb-base + +\ Fixed up later +-1 VALUE io-base + +\ We support only one instance +false VALUE is-installed? + +: vga-io-xlate ( port -- addr ) +  io-base -1 = IF +    dup translate-my-address fff not and to io-base +  THEN +  io-base + +; + +: vga-w! ( value port -- ) +  vga-io-xlate rw!-le +; + +: vga-w@ ( port -- value ) +  vga-io-xlate rw@-le +; + +: vga-b! ( value port -- ) +  vga-io-xlate rb! +; + +: vga-b@ ( port -- value ) +  vga-io-xlate rb@ +; + +: vbe!	( value index -- ) +  1ce vga-w! 1d0 vga-w! +; + +: vbe@	( index -- value ) +  1ce vga-w! 1d0 vga-w@ +; + +: color! ( r g b number -- )  +   3c8 vga-b! +   rot 3c9 vga-b! +   swap 3c9 vga-b! +   3c9 vga-b! +; + +: color@ ( number -- r g b )  +   3c8 vga-b! +   3c9 vga-b@ +   3c9 vga-b@ +   3c9 vga-b@ +; + +: set-colors ( adr number #numbers -- ) +   over 3c8 vga-b! +   swap DO +     rb@ 3c9 vga-b! +     rb@ 3c9 vga-b! +     rb@ 3c9 vga-b! +   LOOP +   3drop +; + +: get-colors ( adr number #numbers -- ) +   3drop +; + +include graphics.fs + +\ qemu fake VBE IO registers +0 CONSTANT VBE_DISPI_INDEX_ID +1 CONSTANT VBE_DISPI_INDEX_XRES +2 CONSTANT VBE_DISPI_INDEX_YRES +3 CONSTANT VBE_DISPI_INDEX_BPP +4 CONSTANT VBE_DISPI_INDEX_ENABLE +5 CONSTANT VBE_DISPI_INDEX_BANK +6 CONSTANT VBE_DISPI_INDEX_VIRT_WIDTH +7 CONSTANT VBE_DISPI_INDEX_VIRT_HEIGHT +8 CONSTANT VBE_DISPI_INDEX_X_OFFSET +9 CONSTANT VBE_DISPI_INDEX_Y_OFFSET +a CONSTANT VBE_DISPI_INDEX_NB + +\ ENABLE register +00 CONSTANT VBE_DISPI_DISABLED +01 CONSTANT VBE_DISPI_ENABLED +02 CONSTANT VBE_DISPI_GETCAPS +20 CONSTANT VBE_DISPI_8BIT_DAC +40 CONSTANT VBE_DISPI_LFB_ENABLED +80 CONSTANT VBE_DISPI_NOCLEARMEM + +: init-mode +  0 3c0 vga-b! +  VBE_DISPI_DISABLED VBE_DISPI_INDEX_ENABLE vbe! +  0 VBE_DISPI_INDEX_X_OFFSET vbe! +  0 VBE_DISPI_INDEX_Y_OFFSET vbe! +  disp-width VBE_DISPI_INDEX_XRES vbe! +  disp-height VBE_DISPI_INDEX_YRES vbe! +  disp-depth VBE_DISPI_INDEX_BPP vbe! +  VBE_DISPI_ENABLED VBE_DISPI_8BIT_DAC or VBE_DISPI_INDEX_ENABLE vbe! +  0 3c0 vga-b! +  20 3c0 vga-b! +; + +: clear-screen +  fb-base disp-width disp-height disp-depth 7 + 8 / * * 0 rfill +; + +: read-settings +  s" qemu,graphic-width" get-chosen IF +     decode-int to disp-width 2drop +  THEN +  s" qemu,graphic-height" get-chosen IF +     decode-int to disp-height 2drop +  THEN +  s" qemu,graphic-depth" get-chosen IF +     decode-int nip nip      +       dup 8 = +       over f = or +       over 10 = or +       over 20 = or IF +         to disp-depth +       ELSE +         ." Unsupported bit depth, using 8bpp " drop cr +       THEN +  THEN +; + +: add-legacy-reg +  \ add legacy I/O Ports / Memory regions to assigned-addresses +  \ see PCI Bus Binding Revision 2.1 Section 7. +  s" reg" get-node get-property IF +    \ "reg" does not exist, create new +    encode-start +  ELSE +    \ "reg" does exist, copy it  +    encode-bytes +  THEN +  \ I/O Range 0x1ce-0x1d2 +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  1ce encode-64+ 4 encode-64+ \ addr size +  \ I/O Range 0x3B0-0x3BB +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  3b0 encode-64+ c encode-64+ \ addr size +  \ I/O Range 0x3C0-0x3DF +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  3c0 encode-64+ 20 encode-64+ \ addr size +  \ Memory Range 0xA0000-0xBFFFF +  my-space a2000000 or encode-int+ \ non-relocatable, <1MB Memory space +  a0000 encode-64+ 20000 encode-64+ \ addr size +  s" reg" property \ store "reg" property +; + +: setup-properties +   \ Shouldn't this be done from open ? +   disp-width encode-int s" width" property +   disp-height encode-int s" height" property +   disp-width disp-depth 7 + 8 / * encode-int s" linebytes" property +   disp-depth encode-int s" depth" property +   s" ISO8859-1" encode-string s" character-set" property \ i hope this is ok... +   \ add "device_type" property +   s" display" device-type +   s" qemu,std-vga" encode-string s" compatible" property +   \ XXX We don't create an "address" property because Linux doesn't know what +   \ to do with it for >32-bit +; + +\ words for installation/removal, needed by is-install/is-remove, see display.fs +: display-remove ( -- )  +; + +: hcall-invert-screen ( -- ) +    frame-buffer-adr frame-buffer-adr 3 +    screen-height screen-width * screen-depth * /x / +    1 hv-logical-memop +    drop +; + +: hcall-blink-screen ( -- ) +    \ 32 msec delay for visually noticing the blink +    hcall-invert-screen 20 ms hcall-invert-screen +; + +: display-install ( -- ) +    is-installed? NOT IF +        ." Installing QEMU fb" cr +        fb-base to frame-buffer-adr +        clear-screen +        default-font  +        set-font +        disp-width disp-height +        disp-width char-width / disp-height char-height / +        disp-depth 7 + 8 /                      ( width height #lines #cols depth ) +        fb-install +	['] hcall-invert-screen to invert-screen +	['] hcall-blink-screen to blink-screen +         true to is-installed? +    THEN +; + +: set-alias +    s" screen" find-alias 0= IF +      \ no previous screen alias defined, define it... +      s" screen" get-node node>path set-alias +    ELSE +       drop +    THEN  +; + + +." qemu vga" cr + +pci-master-enable +pci-mem-enable +pci-io-enable +add-legacy-reg +read-settings +init-mode +init-default-palette +setup-properties +' display-install is-install +' display-remove is-remove +set-alias diff --git a/roms/SLOF/board-qemu/slof/pci-device_1af4_1000.fs b/roms/SLOF/board-qemu/slof/pci-device_1af4_1000.fs new file mode 100644 index 00000000..ac18e0ef --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1af4_1000.fs @@ -0,0 +1,23 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ Handle virtio-net device + +s" virtio [ net ]" type cr + +my-space pci-device-generic-setup + +pci-io-enable + +s" virtio-net.fs" included + +pci-device-disable diff --git a/roms/SLOF/board-qemu/slof/pci-device_1af4_1001.fs b/roms/SLOF/board-qemu/slof/pci-device_1af4_1001.fs new file mode 100644 index 00000000..fb246346 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1af4_1001.fs @@ -0,0 +1,34 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ Handle virtio-blk device + +s" virtio [ block ]" type cr + +my-space pci-device-generic-setup + +pci-master-enable +pci-mem-enable +pci-io-enable + +s" virtio-block.fs" included + +\ Allocate memory for virtio queue: +virtiodev 0 virtio-get-qsize virtio-vring-size +1000 CLAIM VALUE queue-addr + +\ Write queue address into device: +queue-addr c rshift +virtiodev vd>base @ 8 + +rl!-le + +pci-device-disable diff --git a/roms/SLOF/board-qemu/slof/pci-device_1af4_1004.fs b/roms/SLOF/board-qemu/slof/pci-device_1af4_1004.fs new file mode 100644 index 00000000..9c1089ac --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1af4_1004.fs @@ -0,0 +1,24 @@ +\ ***************************************************************************** +\ * Copyright (c) 2012 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ Handle virtio-net device + +s" virtio [ scsi ]" type cr + +my-space pci-device-generic-setup +pci-master-enable +pci-mem-enable +pci-io-enable + +s" virtio-scsi.fs" included + +pci-device-disable diff --git a/roms/SLOF/board-qemu/slof/pci-device_1af4_1009.fs b/roms/SLOF/board-qemu/slof/pci-device_1af4_1009.fs new file mode 100644 index 00000000..03964a6d --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1af4_1009.fs @@ -0,0 +1,34 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ Handle virtio-fs device + +s" virtio [ network ]" type cr + +my-space pci-device-generic-setup + +pci-master-enable +pci-mem-enable +pci-io-enable + +s" virtio-fs.fs" included + +\ Allocate memory for virtio queue: +virtiodev 0 virtio-get-qsize virtio-vring-size +1000 CLAIM VALUE queue-addr + +\ Write queue address into device: +queue-addr c rshift +virtiodev vd>base @ 8 + +rl!-le + +pci-device-disable diff --git a/roms/SLOF/board-qemu/slof/pci-device_8086_100e.fs b/roms/SLOF/board-qemu/slof/pci-device_8086_100e.fs new file mode 100644 index 00000000..8f279a25 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_8086_100e.fs @@ -0,0 +1,23 @@ +\ ***************************************************************************** +\ * Copyright (c) 2013 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ Handle e1000 device + +s" e1000 [ net ]" type cr + +my-space pci-device-generic-setup + +pci-io-enable + +s" e1k.fs" included + +pci-device-disable diff --git a/roms/SLOF/board-qemu/slof/pci-interrupts.fs b/roms/SLOF/board-qemu/slof/pci-interrupts.fs new file mode 100644 index 00000000..e11b7793 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-interrupts.fs @@ -0,0 +1,38 @@ + +: pci-gen-irq-map-one ( prop-addr prop-len slot pin -- prop-addr prop-len ) +        2dup + 4 mod                ( prop-addr prop-len slot pin parentpin ) +        >r >r                       ( prop-addr prop-len slot R: swizzledpin pin ) + +        \ Child slot# +        B lshift encode-int+        ( prop-addr prop-len R: swizzledpin pin ) +        \ Child 64bit BAR (not really used) +        0 encode-64+ +        \ Chile pin# +        r> encode-int+              ( prop-addr prop-len R: swizzledpin ) + +        \ Parent phandle +        get-parent encode-int+ + +        \ Parent slot# +        get-node >space +        pci-addr2dev B lshift       ( prop-addr prop-len parent-slot R: swizzledpin ) +        encode-int+ +        \ Parent 64bit BAR (not really used) +        0 encode-64+ +        \ Parent pin +        r> encode-int+              ( prop-addr prop-len R: ) +; + +: pci-gen-irq-entry ( prop-addr prop-len config-addr -- prop-addr prop-len ) +        pci-addr2dev 4 mod          ( prop-addr prop-len slot ) +        -rot                        ( slot prop-addr prop-len ) +        5 1 DO +                2 pick i            ( slot prop-addr prop-len slot pin ) +                pci-gen-irq-map-one +        LOOP +        rot drop +; + +: pci-set-irq-line ( config-addr -- ) +  drop +; diff --git a/roms/SLOF/board-qemu/slof/pci-phb.fs b/roms/SLOF/board-qemu/slof/pci-phb.fs new file mode 100644 index 00000000..a8fb7ca5 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-phb.fs @@ -0,0 +1,337 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ PAPR PCI host bridge. + +0 VALUE phb-debug? + + +." Populating " pwd cr + +\ needed to find the right path in the device tree +: decode-unit ( addr len -- phys.lo ... phys.hi ) +   2 hex-decode-unit       \ decode string +   b lshift swap           \ shift the devicenumber to the right spot +   8 lshift or             \ add the functionnumber +   \ my-bus 10 lshift or   \ add the busnumber (assume always bus 0) +   0 0 rot                 \ make phys.lo = 0 = phys.mid +; + +\ needed to have the right unit address in the device tree listing +\ phys.lo=phys.mid=0 , phys.hi=config-address +: encode-unit ( phys.lo phys-mid phys.hi -- unit-str unit-len ) +   nip nip                     \ forget the phys.lo and phys.mid +   dup 8 rshift 7 and swap     \ calculate function number +   B rshift 1F and             \ calculate device number +   over IF 2 ELSE nip 1 THEN   \ create string with dev#,fn# or dev# only? +   hex-encode-unit +; + + +0 VALUE my-puid + +: setup-puid +  s" reg" get-node get-property 0= IF +    decode-64 to my-puid 2drop +  THEN +; + +setup-puid + +: config-b@  puid >r my-puid TO puid rtas-config-b@ r> TO puid ; +: config-w@  puid >r my-puid TO puid rtas-config-w@ r> TO puid ; +: config-l@  puid >r my-puid TO puid rtas-config-l@ r> TO puid ; + +\ define the config writes +: config-b!  puid >r my-puid TO puid rtas-config-b! r> TO puid ; +: config-w!  puid >r my-puid TO puid rtas-config-w! r> TO puid ; +: config-l!  puid >r my-puid TO puid rtas-config-l! r> TO puid ; + + +: map-in ( phys.lo phys.mid phys.hi size -- virt ) +   phb-debug? IF cr ." map-in called: " .s cr THEN +   \ Ignore the size, phys.lo and phys.mid, get BAR from config space +   drop nip nip                         ( phys.hi ) +   \ Sanity check whether config address is in expected range: +   dup FF AND dup 10 28 WITHIN NOT swap 30 <> AND IF +      cr ." phys.hi = " . cr +      ABORT" map-in with illegal config space address" +   THEN +   00FFFFFF AND                         \ Need only bus-dev-fn+register bits +   dup config-l@                        ( phys.hi' bar.lo ) +   dup 7 AND 4 = IF                     \ Is it a 64-bit BAR? +      swap 4 + config-l@ lxjoin         \ Add upper part of 64-bit BAR +   ELSE +      nip +   THEN +   F NOT AND                            \ Clear indicator bits +   translate-my-address +   phb-debug? IF ." map-in done: " .s cr THEN +; + +: map-out ( virt size -- ) +   phb-debug? IF ." map-out called: " .s cr THEN +   2drop  +; + + +: dma-alloc ( size -- virt ) +   phb-debug? IF cr ." dma-alloc called: " .s cr THEN +   fff + fff not and                  \ Align size to next 4k boundary +   alloc-mem +   \ alloc-mem always returns aligned memory - double check just to be sure +   dup fff and IF +      ." Warning: dma-alloc got unaligned memory!" cr +   THEN +; + +: dma-free ( virt size -- ) +   phb-debug? IF cr ." dma-free called: " .s cr THEN +   fff + fff not and                  \ Align size to next 4k boundary +   free-mem +; + + +\ Helper variables for dma-map-in and dma-map-out +0 VALUE dma-window-liobn        \ Logical I/O bus number +0 VALUE dma-window-base         \ Start address of window +0 VALUE dma-window-size         \ Size of the window + +0 VALUE bm-handle               \ Bitmap allocator handle +0 VALUE my-virt +0 VALUE my-size +0 VALUE dev-addr +0 VALUE tmp-dev-addr + +\ Read helper variables (LIOBN, DMA window base and size) from the +\ "ibm,dma-window" property. This property can be either located +\ in the PCI device node or in the bus node, so we've got to use the +\ "calling-child" variable here to get to the node that initiated the call. +\ XXX We should search all the way up the tree to the PHB ... +: (init-dma-window-vars)  ( -- ) +\   ." Foo called in " pwd cr +\   ." calling child is " calling-child .node cr +\   ." parent is " calling-child parent .node cr +   s" ibm,dma-window" calling-child get-property IF +       s" ibm,dma-window" calling-child parent get-property  +       ABORT" no dma-window property available" +   THEN +   decode-int TO dma-window-liobn +   decode-64 TO dma-window-base +   decode-64 TO dma-window-size +   2drop +   bm-handle 0= IF +       dma-window-base dma-window-size 1000 bm-allocator-init to bm-handle +       \ Sometimes the window-base appears as zero, that does not +       \ go well with NULL pointers. So block this address +       dma-window-base 0= IF +          bm-handle 1000 bm-alloc drop +       THEN +   THEN +; + +: (clear-dma-window-vars)  ( -- ) +    0 TO dma-window-liobn +    0 TO dma-window-base +    0 TO dma-window-size +; + +\ We assume that firmware never maps more than the whole dma-window-size +\ so we cheat by calculating the remainder of addr/windowsize instead +\ of taking care to maintain a list of assigned device addresses +: dma-virt2dev  ( virt -- devaddr ) +   dma-window-size mod dma-window-base + +; + +: dma-map-in  ( virt size cachable? -- devaddr ) +   phb-debug? IF cr ." dma-map-in called: " .s cr THEN +   (init-dma-window-vars) +   drop                               ( virt size ) + +   to my-size +   to my-virt +   bm-handle my-size bm-alloc +   to dev-addr +   dev-addr 0 < IF +       ." Bitmap allocation Failed " dev-addr . +       FALSE EXIT +   THEN +   dev-addr to tmp-dev-addr + +   my-virt my-size +   bounds dup >r                      ( v+s virt  R: virt ) +   swap fff + fff not and             \ Align end to next 4k boundary +   swap fff not and                   ( v+s' virt'  R: virt ) +   ?DO +       \ ." mapping " i . cr +       dma-window-liobn                \ liobn +       tmp-dev-addr                    \ ioba +       i 3 OR                          \ Make a read- & writeable TCE +       ( liobn ioba tce  R: virt ) +       hv-put-tce ABORT" H_PUT_TCE failed" +       tmp-dev-addr 1000 + to tmp-dev-addr +   1000 +LOOP +   r> drop +   my-virt FFF and dev-addr or +   (clear-dma-window-vars) +; + +: dma-map-out  ( virt devaddr size -- ) +   phb-debug? IF cr ." dma-map-out called: " .s cr THEN +   (init-dma-window-vars) +   to my-size +   to dev-addr +   to my-virt +   dev-addr fff not and to dev-addr +   dev-addr to tmp-dev-addr + +   my-virt my-size                    ( virt size ) +   bounds                             ( v+s virt ) +   swap fff + fff not and             \ Align end to next 4k boundary +   swap fff not and                   ( v+s' virt' ) +   ?DO +       \ ." unmapping " i . cr +       dma-window-liobn                \ liobn +       tmp-dev-addr                    \ ioba +       i                               \ Lowest bits not set => invalid TCE +       ( liobn ioba tce ) +       hv-put-tce ABORT" H_PUT_TCE failed" +       tmp-dev-addr 1000 + to tmp-dev-addr +   1000 +LOOP +   bm-handle dev-addr my-size bm-free +   (clear-dma-window-vars) +; + +: dma-sync  ( virt devaddr size -- ) +   phb-debug? IF cr ." dma-sync called: " .s cr THEN +   \ TODO: Call flush-cache or sync here? +   3drop +; + + +: open  true ; +: close ; + +\ Parse the "ranges" property of the root pci node to decode the available +\ memory ranges. See "PCI Bus Binding to IEEE Std 1275-1994" for details. +\ The memory ranges are then used for setting up the device bars (if necessary) +: phb-parse-ranges ( -- ) +   \ First clear everything, in case there is something missing in the ranges +   0  pci-next-io ! +   0  pci-max-io ! +   0  pci-next-mem ! +   0  pci-max-mem ! +   0  pci-next-mmio ! +   0  pci-max-mmio ! +   0  pci-next-mem64 ! +   0  pci-max-mem64 ! + +   \ Now get the "ranges" property +   s" ranges" get-node get-property 0<> ABORT" ranges property not found" +   ( prop-addr prop-len ) +   BEGIN +      dup +   WHILE +      decode-int                      \ Decode phys.hi +      3000000 AND                     \ Filter out address space in phys.hi +      CASE +         1000000 OF                             \ I/O space? +            decode-64 dup >r pci-next-io !      \ Decode PCI base address +            decode-64 drop                      \ Forget the parent address +            decode-64 r> + pci-max-io !         \ Decode size & calc max address +            pci-next-io @ 0= IF +               pci-next-io @ 10 + pci-next-io ! \ BARs must not be set to zero +            THEN +         ENDOF +         2000000 OF                             \ 32-bit memory space? +            decode-64 pci-next-mem !            \ Decode mem base address +            decode-64 drop                      \ Forget the parent address +            decode-64 2 / dup >r                \ Decode and calc size/2 +            pci-next-mem @ + dup pci-max-mem !  \ and calc max mem address +            dup pci-next-mmio !                 \ which is the same as MMIO base +            r> + pci-max-mmio !                 \ calc max MMIO address +         ENDOF +         3000000 OF                             \ 64-bit memory space? +	    decode-64 pci-next-mem64 ! +	    decode-64 drop                      \ Forget the parent address +	    decode-64 pci-max-mem64 ! +         ENDOF +      ENDCASE +   REPEAT +   ( prop-addr prop-len ) +   2drop + +   phb-debug? IF +     ." pci-next-io   = " pci-next-io @ . cr +     ." pci-max-io    = " pci-max-io  @ . cr +     ." pci-next-mem  = " pci-next-mem @ . cr +     ." pci-max-mem   = " pci-max-mem  @ . cr +     ." pci-next-mmio = " pci-next-mmio @ . cr +     ." pci-max-mmio  = " pci-max-mmio @ . cr +     ." pci-next-mem64  = " pci-next-mem64 @ . cr +     ." pci-max-mem64   = " pci-max-mem64  @ . cr +   THEN +; + +: phb-pci-walk-bridge ( -- ) +    phb-debug? IF ."   Calling pci-walk-bridge " pwd cr THEN + +    get-node child ?dup 0= IF EXIT THEN    \ get and check if we have children +    0 to pci-device-slots                  \ reset slot array to unpoppulated +    BEGIN +        dup                                \ Continue as long as there are children +    WHILE +        dup set-node                       \ Set child node as current node +        my-space pci-set-slot              \ set the slot bit +        my-space pci-htype@                \ read HEADER-Type +        7f and                             \ Mask bit 7 - multifunction device +        CASE +            0 OF my-space pci-device-setup ENDOF  \ | set up the device +            1 OF my-space pci-bridge-setup ENDOF  \ | set up the bridge +            dup OF my-space pci-htype@ pci-out ENDOF +        ENDCASE +        peer +    REPEAT drop +    get-parent set-node +; + +\ Landing routing to probe the popuated device tree +: phb-pci-probe-bus ( busnr -- ) +    drop phb-pci-walk-bridge +; + +\ Stub routine, as qemu has enumerated, we already have the device +\ properties set. +: phb-pci-device-props ( addr -- ) +    dup pci-class-name device-name +    dup pci-device-assigned-addresses-prop +    drop +; + +\ Scan the child nodes of the pci root node to assign bars, fixup +\ properties etc. +: phb-setup-children +   puid >r                          \ Save old value of puid +   my-puid TO puid                  \ Set current puid +   phb-parse-ranges +   1 TO pci-hotplug-enabled +   s" qemu,phb-enumerated" get-node get-property 0<> IF +       1 0 (probe-pci-host-bridge) +   ELSE +       2drop +       ['] phb-pci-probe-bus TO func-pci-probe-bus +       ['] phb-pci-device-props TO func-pci-device-props +       phb-pci-walk-bridge          \ PHB device tree is already populated. +   THEN +   r> TO puid                       \ Restore previous puid +; +phb-setup-children diff --git a/roms/SLOF/board-qemu/slof/qemu-bootlist.fs b/roms/SLOF/board-qemu/slof/qemu-bootlist.fs new file mode 100644 index 00000000..4778e162 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/qemu-bootlist.fs @@ -0,0 +1,61 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +defer set-boot-device +defer add-boot-device + +8 CONSTANT MAX-ALIAS +: add-boot-aliases ( str -- ) +    2dup add-boot-device               ( $str ) +    MAX-ALIAS 1 DO +	2dup i $cathex 2dup              ( $str $strN $strN ) +	find-alias 0 > IF                ( $str $strN false | $result ) +	    drop strdup add-boot-device  ( $str ) +	ELSE 2drop THEN +    LOOP +    2drop +; + +: qemu-read-bootlist ( -- ) +   \ See if QEMU has set exact boot device list +   " qemu,boot-list" get-chosen IF +        s" boot-device" $setenv +        EXIT +   THEN + +   0 0 set-boot-device + +   " qemu,boot-device" get-chosen not IF +      \ No boot list set from qemu, so check nvram +      " boot-device" evaluate swap drop 0= IF +         \ Not set in nvram too, set default disk/cdrom alias +         " disk" add-boot-aliases +         " cdrom" add-boot-aliases +         " net" add-boot-aliases +      THEN +      EXIT +   THEN + +   0 ?DO +       dup i + c@ CASE +           0        OF ENDOF +           [char] a OF ENDOF +           [char] b OF ENDOF +           [char] c OF " disk"  add-boot-aliases ENDOF +           [char] d OF " cdrom" add-boot-aliases ENDOF +           [char] n OF " net"   add-boot-aliases ENDOF +       ENDCASE cr +   LOOP +   drop +; + +' qemu-read-bootlist to read-bootlist diff --git a/roms/SLOF/board-qemu/slof/rtas-nvram.fs b/roms/SLOF/board-qemu/slof/rtas-nvram.fs new file mode 100644 index 00000000..fdebfb23 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/rtas-nvram.fs @@ -0,0 +1,48 @@ +\ ***************************************************************************** +\ * Copyright (c) 2012 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +." Populating " pwd cr + +0 VALUE my-nvram-fetch +0 VALUE my-nvram-store +0 VALUE my-nvram-size +0 VALUE nvram-addr + +: open true ; +: close ; + +: write ( adr len -- actual ) +  nip +; + +: read  ( adr len -- actual ) +  nip +; + +: setup-alias +    " nvram" find-alias 0= IF +        " nvram" get-node node>path set-alias +    ELSE +        drop +    THEN +; + +" #bytes" get-node get-package-property 0= IF +    decode-int to my-nvram-size 2drop +    " nvram-fetch" rtas-get-token to my-nvram-fetch +    " nvram-store" rtas-get-token to my-nvram-store +    my-nvram-size to nvram-size +    nvram-size alloc-mem to nvram-addr +    my-nvram-fetch my-nvram-store nvram-size nvram-addr internal-nvram-init +THEN + +setup-alias diff --git a/roms/SLOF/board-qemu/slof/rtas.fs b/roms/SLOF/board-qemu/slof/rtas.fs new file mode 100644 index 00000000..2e10b0a5 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/rtas.fs @@ -0,0 +1,189 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ KVM/qemu RTAS + +\ rtas control block + +371 cp + +STRUCT +    /l field rtas>token +    /l field rtas>nargs +    /l field rtas>nret +    /l field rtas>args0 +    /l field rtas>args1 +    /l field rtas>args2 +    /l field rtas>args3 +    /l field rtas>args4 +    /l field rtas>args5 +    /l field rtas>args6 +    /l field rtas>args7 +    /l C * field rtas>args +    /l field rtas>bla +CONSTANT /rtas-control-block + +CREATE rtas-cb /rtas-control-block allot +rtas-cb /rtas-control-block erase + +0 VALUE rtas-base +0 VALUE rtas-size +0 VALUE rtas-entry +0 VALUE rtas-node + +\ Locate qemu RTAS, remove the linux,... properties we really don't +\ want them to stick around + +372 cp + +: find-qemu-rtas ( -- ) +    " /rtas" find-device get-node to rtas-node + +    " linux,rtas-base" rtas-node get-package-property IF +         device-end EXIT THEN +    drop l@ to rtas-base +    " linux,rtas-base" delete-property + +    " rtas-size" rtas-node get-package-property IF +         device-end EXIT THEN +    drop l@ to rtas-size + +    " linux,rtas-entry" rtas-node get-package-property IF +        rtas-base to rtas-entry +    ELSE +        drop l@ to rtas-entry +        " linux,rtas-entry" delete-property +    THEN + +\    ." RTAS found, base=" rtas-base . ."  size=" rtas-size . cr + +    \ Patch the RTAS blob with our sc1 patcher if necessary +    0 +    rtas-base +    dup rtas-size + +    check-and-patch-sc1 + +    device-end +; +find-qemu-rtas +373 cp + +: enter-rtas ( -- ) +    rtas-cb rtas-base 0 rtas-entry call-c drop +; + +: rtas-get-token ( str len -- token | 0 ) +    rtas-node get-package-property IF 0 ELSE drop l@ THEN +; + +#include <rtas/rtas-reboot.fs> +#include <rtas/rtas-cpu.fs> + +: rtas-set-tce-bypass ( unit enable -- ) +    " ibm,set-tce-bypass" rtas-get-token rtas-cb rtas>token l! +    2 rtas-cb rtas>nargs l! +    0 rtas-cb rtas>nret l! +    rtas-cb rtas>args1 l! +    rtas-cb rtas>args0 l! +    enter-rtas +; + +: rtas-quiesce ( -- ) +    " quiesce" rtas-get-token rtas-cb rtas>token l! +    0 rtas-cb rtas>nargs l! +    0 rtas-cb rtas>nret l! +    enter-rtas +; + + +0 value puid + +: rtas-do-config-@ ( config-addr size -- value) +    \ We really want to cache this ! +    " ibm,read-pci-config" rtas-get-token rtas-cb rtas>token l! +    4 rtas-cb rtas>nargs l! +    2 rtas-cb rtas>nret l! +    ( addr size ) rtas-cb rtas>args3 l! +    puid ffffffff and rtas-cb rtas>args2 l! +    puid 20 rshift rtas-cb rtas>args1 l! +    ( addr ) rtas-cb rtas>args0 l! +    enter-rtas +    rtas-cb rtas>args4 l@ dup IF +        \ Do not warn on error as this is part of the +	\ normal PCI probing pass +	drop ffffffff +    ELSE +	drop rtas-cb rtas>args5 l@ +    THEN +; + +: rtas-do-config-! ( value config-addr size ) +    \ We really want to cache this ! +    " ibm,write-pci-config" rtas-get-token rtas-cb rtas>token l! +    5 rtas-cb rtas>nargs l! +    1 rtas-cb rtas>nret l! +    ( value addr size ) rtas-cb rtas>args3 l! +    puid ffffffff and rtas-cb rtas>args2 l! +    puid 20 rshift rtas-cb rtas>args1 l! +    ( value addr ) rtas-cb rtas>args0 l! +    ( value ) rtas-cb rtas>args4 l! +    enter-rtas +    rtas-cb rtas>args5 l@ dup IF +    	    ." RTAS write config err " . cr +    ELSE drop THEN +; + +: rtas-config-b@ ( config-addr -- value ) +  1 rtas-do-config-@ ff and +; +: rtas-config-b! ( value config-addr -- ) +  1 rtas-do-config-! +; +: rtas-config-w@ ( config-addr -- value ) +  2 rtas-do-config-@ ffff and +; +: rtas-config-w! ( value config-addr -- ) +  2 rtas-do-config-! +; +: rtas-config-l@ ( config-addr -- value ) +  4 rtas-do-config-@ ffffffff and +; +: rtas-config-l! ( value config-addr -- ) +  4 rtas-do-config-! +; + +: of-start-cpu rtas-start-cpu ; + +' power-off to halt +' rtas-system-reboot to reboot + +\ Methods of the rtas node proper +rtas-node set-node + +: open true ; +: close ; + +: instantiate-rtas ( adr -- entry ) +    dup rtas-base swap rtas-size move +    dup rtas-entry rtas-base - + +    2dup hv-rtas-update dup 0 <> IF +	\ Ignore hcall not implemented error, print error otherwise +	dup -2 <> IF ." HV-RTAS-UPDATE error: " . cr ELSE drop THEN +    ELSE +	drop +    THEN +    nip +; + +device-end + +374 cp diff --git a/roms/SLOF/board-qemu/slof/tree.fs b/roms/SLOF/board-qemu/slof/tree.fs new file mode 100644 index 00000000..4aba4c53 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/tree.fs @@ -0,0 +1,193 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +: strequal ( str1 len1 str2 len2 -- flag ) +  rot dup rot = IF comp 0= ELSE 2drop drop 0 THEN ;  + +400 cp + +\ The root of the device tree and some of its kids. +" /" find-device + +\ The following properties have been provided by the FDT from QEMU already, +\ so we do not have to create them on our own: + +\ " QEMU" encode-string s" model" property +\ 2 encode-int s" #address-cells" property +\ 2 encode-int s" #size-cells" property +\ s" chrp" device-type + +480 cp + +\ See 3.6.5, and the PowerPC OF binding document. +new-device +s" mmu" 2dup device-name device-type +0 0 s" translations" property + +: open  true ; +: close ; + +finish-device +device-end + +4c0 cp + +\ Fixup timebase frequency from device-tree +: fixup-tbfreq +    " /cpus/@0" find-device +    " timebase-frequency" get-node get-package-property IF +        2drop +    ELSE +        decode-int to tb-frequency 2drop +    THEN +    device-end +; +fixup-tbfreq + +4d0 cp + +include fbuffer.fs + +500 cp + +: populate-vios ( -- ) +    \ Populate the /vdevice children with their methods +    \ WARNING: Quite a few SLOFisms here like get-node, set-node, ... + +    ." Populating /vdevice methods" cr +    " /vdevice" find-device get-node child +    BEGIN +        dup 0 <> +    WHILE +        dup set-node +        dup " compatible" rot get-package-property 0 = IF +            drop dup from-cstring +            2dup " hvterm1" strequal IF +                " vio-hvterm.fs" included +            THEN +            2dup " IBM,v-scsi" strequal IF +                " vio-vscsi.fs" included +            THEN +            2dup " IBM,l-lan" strequal IF +                " vio-veth.fs" included +            THEN +	    2dup " qemu,spapr-nvram" strequal IF +	    	" rtas-nvram.fs" included +	    THEN +            2drop +       THEN +       peer +    REPEAT drop + +    device-end +; + +\ Now do it +populate-vios + +580 cp + +5a0 cp + +#include "pci-scan.fs" + +: populate-pci-busses ( -- ) +    \ Populate the /pci* children with their methods +    " /" find-device get-node child +    BEGIN +        dup 0 <> +    WHILE +        dup set-node +        dup " name" rot get-package-property 0 = IF +            drop dup from-cstring +            2dup s" pci" strequal IF +                s" pci-phb.fs" included +            THEN +            2drop +       THEN +       peer +    REPEAT drop + +    device-end +; + +populate-pci-busses + +600 cp + +: check-patch-kernel-sc1 ( -- ) +    \ At this point we can try our best to patch the kernel. This function +    \ gets called from the "quiesce" call that kernels execute before they +    \ take over the system. +    \ +    \ Here we know that ciregs->r4 contains the return address that gets us +    \ back into enter_prom inside the guest kernel. +    \ We assume that within a range of +- 16MB of that pointer all sc 1 +    \ instructions inside of that kernel reside. + +    \ test_ins (instruction that tells us the kernel's endianness; we use the +    \           return address back into the kernel here.) +    ciregs >r4 @ +    \ test_ins + 16MB (end of search range) +    dup 1000000 + +    \ MAX(test_ins - 16MB, 0) (start of search range) +    dup 2000000 < IF 0 ELSE dup 2000000 - THEN +    swap +    check-and-patch-sc1 +; + +\ Add sc 1 patching +' check-patch-kernel-sc1 add-quiesce-xt + +\ Add rtas cleanup last +' rtas-quiesce add-quiesce-xt + +640 cp + +690 cp + +6a0 cp + +6a8 cp + +6b0 cp + +6b8 cp + +6c0 cp + +s" /cpus/@0" open-dev encode-int s" cpu" set-chosen +s" /memory@0" open-dev encode-int s" memory" set-chosen + +6e0 cp + +700 cp + +\ See 3.5. +s" /openprom" find-device +   s" SLOF," slof-build-id here swap rmove here slof-build-id nip $cat encode-string s" model" property +   0 0 s" relative-addressing" property +device-end + +s" /aliases" find-device +   : open  true ; +   : close ; +device-end + +s" /mmu" open-dev encode-int s" mmu" set-chosen + +#include "available.fs" + +\ Setup terminal IO + +#include <term-io.fs> + diff --git a/roms/SLOF/board-qemu/slof/version.S b/roms/SLOF/board-qemu/slof/version.S new file mode 100644 index 00000000..9aa2a94f --- /dev/null +++ b/roms/SLOF/board-qemu/slof/version.S @@ -0,0 +1,36 @@ +/****************************************************************************** + * Copyright (c) 2010, 2011 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + *     IBM Corporation - initial implementation + *****************************************************************************/ + +/* + * Print version information - in SLOF + * This code is in a separate file so that it can be easily compiled during + * each new build (for refreshing the build date). + */ + +#include "termctrl.h" +#include <product.h> + +.global print_version +print_version: +	.ascii	TERM_CTRL_RESET +	.ascii	TERM_CTRL_CRSOFF +	.ascii	TERM_CTRL_BRIGHT +	.ascii	PRODUCT_NAME +	.ascii  " Starting\r\n" +	.ascii  TERM_CTRL_RESET +	.ascii  " Build Date = ", __DATE__, " ", __TIME__ +	.ascii	"\r\n" +	.ascii  " FW Version = " , RELEASE +	.ascii	"\r\n\0" +	.align	2 +.global print_version_end +print_version_end: diff --git a/roms/SLOF/board-qemu/slof/vio-hvterm.fs b/roms/SLOF/board-qemu/slof/vio-hvterm.fs new file mode 100644 index 00000000..3519751e --- /dev/null +++ b/roms/SLOF/board-qemu/slof/vio-hvterm.fs @@ -0,0 +1,41 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +." Populating " pwd cr + +: open true ; +: close ; + +: write ( adr len -- actual ) +   tuck +   0 ?DO +       dup c@ my-unit SWAP hv-putchar +       1 + +   LOOP +   drop +; + +: read  ( adr len -- actual ) +   0= IF drop 0 EXIT THEN +   my-unit hv-haschar 0= IF 0 swap c! -2 EXIT THEN +   my-unit hv-getchar swap c! 1 +; + +: setup-alias +    " hvterm" find-alias 0= IF +        " hvterm" get-node node>path set-alias +    ELSE +        drop +    THEN +; + +setup-alias diff --git a/roms/SLOF/board-qemu/slof/vio-veth.fs b/roms/SLOF/board-qemu/slof/vio-veth.fs new file mode 100644 index 00000000..3c8f489f --- /dev/null +++ b/roms/SLOF/board-qemu/slof/vio-veth.fs @@ -0,0 +1,76 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +." Populating " pwd cr + +" network" device-type + +INSTANCE VARIABLE obp-tftp-package +0 VALUE veth-priv +0 VALUE open-count + +: open  ( -- okay? ) +   open-count 0= IF +      my-unit 1 rtas-set-tce-bypass +      s" local-mac-address" get-node get-property not +      s" reg" get-node get-property not 3 pick and IF +         >r nip r> +         libveth-open dup not IF ." libveth-open failed" EXIT THEN +         drop TO veth-priv +      THEN +   THEN +   my-args s" obp-tftp" $open-package obp-tftp-package ! +   open-count 1 + to open-count +   true +; + +: close  ( -- ) +   open-count 0> IF +      open-count 1 - dup to open-count +      0= IF +         veth-priv libveth-close +         my-unit 0 rtas-set-tce-bypass +      THEN +   THEN +   s" close" obp-tftp-package @ $call-method +; + +: read ( buf len -- actual ) +   dup IF +      veth-priv libveth-read +   ELSE +      nip +   THEN +; + +: write ( buf len -- actual ) +   dup IF +      veth-priv libveth-write +   ELSE +      nip +   THEN +; + +: load  ( addr -- len ) +    s" load" obp-tftp-package @ $call-method  +; + +: ping  ( -- ) +    s" ping" obp-tftp-package @ $call-method +; + +: setup-alias +    " net" get-next-alias ?dup IF +        get-node node>path set-alias +    THEN +; +setup-alias diff --git a/roms/SLOF/board-qemu/slof/vio-vscsi.fs b/roms/SLOF/board-qemu/slof/vio-vscsi.fs new file mode 100644 index 00000000..f2d4c6fc --- /dev/null +++ b/roms/SLOF/board-qemu/slof/vio-vscsi.fs @@ -0,0 +1,546 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +." Populating " pwd + +false VALUE vscsi-debug? +0 VALUE vscsi-unit + +\ ----------------------------------------------------------- +\ Direct DMA conversion hack +\ ----------------------------------------------------------- +: l2dma ( laddr - dma_addr)       +; + +\ ----------------------------------------------------------- +\ CRQ related functions +\ ----------------------------------------------------------- + +0    VALUE     crq-real-base +0    VALUE     crq-base +0    VALUE     crq-dma +0    VALUE     crq-offset +1000 CONSTANT  CRQ-SIZE + +CREATE crq 10 allot + +: crq-alloc ( -- ) +    \ Allocate enough to align to a page +    CRQ-SIZE fff + alloc-mem to crq-real-base +    \ align the result +    crq-real-base fff + fffff000 AND to crq-base 0 to crq-offset +    crq-base l2dma to crq-dma +; + +: crq-free ( -- ) +    vscsi-unit hv-free-crq +    crq-real-base CRQ-SIZE fff + free-mem 0 to crq-base 0 to crq-real-base +; + +: crq-init ( -- res ) +    \ Allocate CRQ. XXX deal with fail +    crq-alloc + +    vscsi-debug? IF +        ." VSCSI: allocated crq at " crq-base . cr +    THEN + +    \ Clear buffer +    crq-base CRQ-SIZE erase + +    \ Register with HV +    vscsi-unit crq-dma CRQ-SIZE hv-reg-crq + +    \ Fail case +    dup 0 <> IF +        ." VSCSI: Error " . ."  registering CRQ !" cr +	crq-free +    THEN +; + +: crq-cleanup ( -- ) +    crq-base 0 = IF EXIT THEN + +    vscsi-debug? IF +        ." VSCSI: freeing crq at " crq-base . cr +    THEN +    crq-free +; + +: crq-send ( msgaddr -- true | false ) +    vscsi-unit swap hv-send-crq 0 = +; + +: crq-poll ( -- true | false) +    crq-offset crq-base + dup +    vscsi-debug? IF +        ." VSCSI: crq poll " dup . +    THEN +    c@ +    vscsi-debug? IF +        ."  value=" dup . cr +    THEN +    80 and 0 <> IF +        dup crq 10 move +	0 swap c! +	crq-offset 10 + dup CRQ-SIZE >= IF drop 0 THEN to crq-offset +	true +    ELSE drop false THEN +; + +: crq-wait ( -- true | false) +    \ FIXME: Add timeout +    0 BEGIN drop crq-poll dup not WHILE d# 1 ms REPEAT +    dup not IF +        ." VSCSI: Timeout waiting response !" cr EXIT +    ELSE +        vscsi-debug? IF +            ." VSCSI: got crq: " crq dup l@ . ."  " 4 + dup l@ . ."  " +	    4 + dup l@ . ."  " 4 + l@ . cr +        THEN +    THEN +; + +\ ----------------------------------------------------------- +\ CRQ encapsulated SRP definitions +\ ----------------------------------------------------------- + +01 CONSTANT VIOSRP_SRP_FORMAT +02 CONSTANT VIOSRP_MAD_FORMAT +03 CONSTANT VIOSRP_OS400_FORMAT +04 CONSTANT VIOSRP_AIX_FORMAT +06 CONSTANT VIOSRP_LINUX_FORMAT +07 CONSTANT VIOSRP_INLINE_FORMAT + +struct +   1 field >crq-valid +   1 field >crq-format +   1 field >crq-reserved +   1 field >crq-status +   2 field >crq-timeout +   2 field >crq-iu-len +   8 field >crq-iu-data-ptr +constant /crq + +: srp-send-crq ( addr len -- ) +    80                crq >crq-valid c! +    VIOSRP_SRP_FORMAT crq >crq-format c! +    0                 crq >crq-reserved c! +    0                 crq >crq-status c! +    0                 crq >crq-timeout w! +    ( len )           crq >crq-iu-len w! +    ( addr ) l2dma    crq >crq-iu-data-ptr x! +    crq crq-send +    not IF +        ." VSCSI: Error sending CRQ !" cr +    THEN +; + +: srp-wait-crq ( -- [tag true] | false ) +    crq-wait not IF false EXIT THEN + +    crq >crq-format c@ VIOSRP_SRP_FORMAT <> IF +    	." VSCSI: Unsupported SRP response: " +	crq >crq-format c@ . cr +	false EXIT +    THEN + +    crq >crq-iu-data-ptr x@ true +; + +\ Add scsi functions to dictionary +scsi-open + + +\ ----------------------------------------------------------- +\ SRP definitions +\ ----------------------------------------------------------- + +0 VALUE >srp_opcode + +00 CONSTANT SRP_LOGIN_REQ +01 CONSTANT SRP_TSK_MGMT +02 CONSTANT SRP_CMD +03 CONSTANT SRP_I_LOGOUT +c0 CONSTANT SRP_LOGIN_RSP +c1 CONSTANT SRP_RSP +c2 CONSTANT SRP_LOGIN_REJ +80 CONSTANT SRP_T_LOGOUT +81 CONSTANT SRP_CRED_REQ +82 CONSTANT SRP_AER_REQ +41 CONSTANT SRP_CRED_RSP +42 CONSTANT SRP_AER_RSP + +02 CONSTANT SRP_BUF_FORMAT_DIRECT +04 CONSTANT SRP_BUF_FORMAT_INDIRECT + +struct +   1 field >srp-login-opcode +   3 + +   8 field >srp-login-tag +   4 field >srp-login-req-it-iu-len +   4 + +   2 field >srp-login-req-buf-fmt +   1 field >srp-login-req-flags +   5 + +  10 field >srp-login-init-port-ids +  10 field >srp-login-trgt-port-ids +constant /srp-login + +struct +   1 field >srp-lresp-opcode +   3 + +   4 field >srp-lresp-req-lim-delta +   8 field >srp-lresp-tag +   4 field >srp-lresp-max-it-iu-len +   4 field >srp-lresp-max-ti-iu-len +   2 field >srp-lresp-buf-fmt +   1 field >srp-lresp-flags +constant /srp-login-resp + +struct +   1 field >srp-lrej-opcode +   3 + +   4 field >srp-lrej-reason +   8 field >srp-lrej-tag +   8 + +   2 field >srp-lrej-buf-fmt +constant /srp-login-rej + +00 CONSTANT SRP_NO_DATA_DESC +01 CONSTANT SRP_DATA_DESC_DIRECT +02 CONSTANT SRP_DATA_DESC_INDIRECT + +struct +    1 field >srp-cmd-opcode +    1 field >srp-cmd-sol-not +    3 + +    1 field >srp-cmd-buf-fmt +    1 field >srp-cmd-dout-desc-cnt +    1 field >srp-cmd-din-desc-cnt +    8 field >srp-cmd-tag +    4 + +    8 field >srp-cmd-lun +    1 + +    1 field >srp-cmd-task-attr +    1 + +    1 field >srp-cmd-add-cdb-len +   10 field >srp-cmd-cdb +    0 field >srp-cmd-cdb-add +constant /srp-cmd + +struct +    1 field >srp-rsp-opcode +    1 field >srp-rsp-sol-not +    2 + +    4 field >srp-rsp-req-lim-delta +    8 field >srp-rsp-tag +    2 + +    1 field >srp-rsp-flags +    1 field >srp-rsp-status +    4 field >srp-rsp-dout-res-cnt +    4 field >srp-rsp-din-res-cnt +    4 field >srp-rsp-sense-len +    4 field >srp-rsp-resp-len +    0 field >srp-rsp-data +constant /srp-rsp + +\ Constants for srp-rsp-flags +01 CONSTANT SRP_RSP_FLAG_RSPVALID +02 CONSTANT SRP_RSP_FLAG_SNSVALID +04 CONSTANT SRP_RSP_FLAG_DOOVER +05 CONSTANT SRP_RSP_FLAG_DOUNDER +06 CONSTANT SRP_RSP_FLAG_DIOVER +07 CONSTANT SRP_RSP_FLAG_DIUNDER + +\ Storage for up to 256 bytes SRP request */ +CREATE srp 100 allot +0 VALUE srp-len + +: srp-prep-cmd-nodata ( srplun -- ) +    srp /srp-cmd erase +    SRP_CMD srp >srp-cmd-opcode c! +    1 srp >srp-cmd-tag x! +    srp >srp-cmd-lun x!         \ 8 bytes lun +    /srp-cmd to srp-len    +; + +: srp-prep-cmd-io ( addr len srplun -- ) +    srp-prep-cmd-nodata		( addr len ) +    swap l2dma			( len dmaaddr ) +    srp srp-len +    		( len dmaaddr descaddr ) +    dup >r x! r> 8 +		( len descaddr+8 ) +    dup 0 swap l! 4 +		( len descaddr+c ) +    l!     +    srp-len 10 + to srp-len +; + +: srp-prep-cmd-read ( addr len srplun -- ) +    srp-prep-cmd-io +    01 srp >srp-cmd-buf-fmt c!	\ in direct buffer +    1 srp >srp-cmd-din-desc-cnt c! +; + +: srp-prep-cmd-write ( addr len srplun -- ) +    srp-prep-cmd-io +    10 srp >srp-cmd-buf-fmt c!	\ out direct buffer +    1 srp >srp-cmd-dout-desc-cnt c! +; + +: srp-send-cmd ( -- ) +    vscsi-debug? IF +        ." VSCSI: Sending SCSI cmd " srp >srp-cmd-cdb c@ . cr +    THEN +    srp srp-len srp-send-crq +; + +: srp-rsp-find-sense ( -- addr len true | false ) +    srp >srp-rsp-flags c@ SRP_RSP_FLAG_SNSVALID and 0= IF +        false EXIT +    THEN +    \ XXX FIXME: We assume the sense data is right at response +    \            data. A different server might actually have both +    \            some response data we need to skip *and* some sense +    \            data. +    srp >srp-rsp-data srp >srp-rsp-sense-len l@ true +; + +\ Wait for a response to the last sent SRP command +\ returns a SCSI status code or -1 (HW error). +\ +: srp-wait-rsp ( -- stat ) +    srp-wait-crq not IF false EXIT THEN +    dup 1 <> IF +        ." VSCSI: Invalid CRQ response tag, want 1 got " . cr +	-1 EXIT +    THEN drop +     +    srp >srp-rsp-tag x@ dup 1 <> IF +        ." VSCSI: Invalid SRP response tag, want 1 got " . cr +	-1 EXIT +    THEN drop +     +    srp >srp-rsp-status c@ +    vscsi-debug? IF +        ." VSCSI: Got response status: " +	dup .status-text cr +    THEN +; + +\ ----------------------------------------------------------- +\ Perform SCSI commands +\ ----------------------------------------------------------- + +8000000000000000 INSTANCE VALUE current-target + +\ SCSI command. We do *NOT* implement the "standard" execute-command +\ because that doesn't have a way to return the sense buffer back, and +\ we do have auto-sense with some hosts. Instead we implement a made-up +\ do-scsi-command. +\ +\ Note: stat is -1 for "hw error" (ie, error queuing the command or +\ getting the response). +\ +\ A sense buffer is returned whenever the status is non-0 however +\ if sense-len is 0 then no sense data is actually present +\ + +: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... ) +                       ( ... [ sense-buf sense-len ] stat ) +    \ Stash command addr & len +    >r >r				( buf-addr buf-len dir ) +    \ Command has no data ? +    over 0= IF +        3drop current-target srp-prep-cmd-nodata +    ELSE +        \ Command is a read ? +        current-target swap IF srp-prep-cmd-read ELSE srp-prep-cmd-write THEN +    THEN +    \ Recover command and copy it to our srp buffer +    r> r> +    srp >srp-cmd-cdb swap move +    srp-send-cmd +    srp-wait-rsp + +    \ Check for HW error +    dup -1 = IF +        0 0 rot EXIT +    THEN + +    \ Other error status +    dup 0<> IF +       srp-rsp-find-sense IF +           vscsi-debug? IF +               over scsi-get-sense-data +               ." VSCSI: Sense key [ " dup . ." ] " .sense-text +	       ."  ASC,ASCQ: " . . cr +           THEN +       ELSE 0 0 +           \ This relies on auto-sense from qemu... if that isn't always the +           \ case we should request sense here +           ." VSCSI: No sense data" cr +       THEN +       rot +    THEN +; + +\ -------------------------------- +\ Include the generic host helpers +\ -------------------------------- + +" scsi-host-helpers.fs" included + +TRUE VALUE first-time-init? +0 VALUE open-count + +\ Cleanup behind us +: vscsi-cleanup +    vscsi-debug? IF ." VSCSI: Cleaning up" cr THEN +    crq-cleanup + +    \ Disable TCE bypass: +    vscsi-unit 0 rtas-set-tce-bypass +; + +\ Initialize our vscsi instance +: vscsi-init ( -- true | false ) +    vscsi-debug? IF ." VSCSI: Initializing" cr THEN + +    my-unit to vscsi-unit + +    \ Enable TCE bypass special qemu feature +    vscsi-unit 1 rtas-set-tce-bypass + +    \ Initialize CRQ +    crq-init 0 <> IF false EXIT THEN + +    \ Send init command +    " "(C0 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00)" drop +    crq-send not IF +        ." VSCSI: Error sending init command" +        crq-cleanup false EXIT +    THEN +  +    \ Wait reply +    crq-wait not IF +        crq-cleanup false EXIT +    THEN + +    \ Check init reply +    crq c@ c0 <> crq 1 + c@ 02 <> or IF +        ." VSCSI: Initial handshake failed" +	crq-cleanup false EXIT +    THEN + +    \ We should now login etc.. but we really don't need to +    \ with our qemu model + +    \ Ensure we cleanup after booting +    first-time-init? IF +        ['] vscsi-cleanup add-quiesce-xt +	false to first-time-init? +    THEN + +    true +; + +: open +    vscsi-debug? IF ." VSCSI: Opening (count is " open-count . ." )" cr THEN + +    open-count 0= IF +        vscsi-init IF +	    1 to open-count true +	ELSE ." VSCSI initialization failed !" cr false THEN +    ELSE +        open-count 1 + to open-count +        true +    THEN +; + +: close +    vscsi-debug? IF ." VSCSI: Closing (count is " open-count . ." )" cr THEN + +    open-count 0> IF +        open-count 1 - dup to open-count +	0= IF +	    vscsi-cleanup +	THEN +    THEN +; + +\ ----------------------------------------------------------- +\ SCSI scan at boot and child device support +\ ----------------------------------------------------------- + +\ We use SRP luns of the form 8000 | (bus << 8) | (id << 5) | lun +\ in the top 16 bits of the 64-bit LUN +: (set-target) +    to current-target +; + +: dev-generate-srplun ( target lun -- ) +    swap 8 << 8000 or or 30 << +; + +\ We obtain here a unit address on the stack, since our #address-cells +\ is 2, the 64-bit srplun is split in two cells that we need to join +\ +\ Note: This diverges a bit from the original OF scsi spec as the two +\ cells are the 2 words of a 64-bit SRP LUN +: set-address ( srplun.lo srplun.hi -- ) +    lxjoin (set-target) +; + +\ We set max-transfer to a fixed value for now to avoid problems +\ with some CD-ROM drives. +\ FIXME: Check max transfer coming from VSCSI +: max-transfer ( -- n ) +    10000 \ Larger value seem to have problems with some CDROMs +; + +8 CONSTANT #dev +: dev-max-target ( -- #max-target ) +    #dev +; + +" scsi-probe-helpers.fs" included + +\ Remove scsi functions from word list +scsi-close + +: setup-alias +    " scsi" find-alias 0= IF +        " scsi" get-node node>path set-alias +    ELSE +        drop +    THEN  +; + +: vscsi-init-and-scan  ( -- ) +    \ Create instance for scanning: +    0 0 get-node open-node ?dup 0= IF EXIT THEN +    my-self >r +    dup to my-self +    \ Scan the VSCSI bus: +    scsi-find-disks +    setup-alias +    \ Close the temporary instance: +    close-node +    r> to my-self +; + +: vscsi-add-disk +    " scsi-disk.fs" included +; + +vscsi-add-disk +vscsi-init-and-scan diff --git a/roms/SLOF/board-qemu/slof/virtio-block.fs b/roms/SLOF/board-qemu/slof/virtio-block.fs new file mode 100644 index 00000000..ea388fb0 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/virtio-block.fs @@ -0,0 +1,89 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ ." Populating " pwd cr + +s" block" device-type + +FALSE VALUE initialized? + +\ Required interface for deblocker + +200 VALUE block-size +8000 CONSTANT max-transfer  + +INSTANCE VARIABLE deblocker + +/vd-len BUFFER: virtiodev +virtiodev virtio-setup-vd + +\ Quiesce the virtqueue of this device so that no more background +\ transactions can be pending. +: shutdown  ( -- ) +    initialized? IF +        my-phandle node>path open-dev ?dup IF +            virtiodev virtio-blk-shutdown +            close-dev +        THEN +        FALSE to initialized? +    THEN +; + +\ Basic device initialization - which has only to be done once +: init  ( -- ) +   virtiodev virtio-blk-init to block-size +   TRUE to initialized? +   ['] shutdown add-quiesce-xt +; + +\ Read multiple blocks - called by deblocker package +: read-blocks  ( addr block# #blocks -- #read ) +   virtiodev virtio-blk-read +; + +\ Standard node "open" function +: open  ( -- okay? ) +   open 0= IF false EXIT THEN +   dup initialized? 0= AND IF +      init +   THEN +   0 0 s" deblocker" $open-package dup deblocker ! dup IF +      s" disk-label" find-package IF +         my-args rot interpose +      THEN +   THEN +   0<> +; + +\ Standard node "close" function +: close  ( -- ) +   deblocker @ close-package +   close +; + +\ Standard node "seek" function +: seek  ( pos.lo pos.hi -- status ) +   s" seek" deblocker @ $call-method +; + +\ Standard node "read" function +: read  ( addr len -- actual ) +   s" read" deblocker @ $call-method +; + +\ Set disk alias if none is set yet +: (set-alias) +   s" disk" get-next-alias ?dup IF +      get-node node>path set-alias +   THEN +; +(set-alias) diff --git a/roms/SLOF/board-qemu/slof/virtio-fs.fs b/roms/SLOF/board-qemu/slof/virtio-fs.fs new file mode 100644 index 00000000..8632b465 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/virtio-fs.fs @@ -0,0 +1,96 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +." Populating " pwd cr + +s" network" device-type + +0 VALUE virtfs-rx-buffer +0 VALUE virtfs-tx-buffer +FALSE VALUE initialized? + +2000 CONSTANT VIRTFS-BUF-SIZE \ 8k + +/vd-len BUFFER: virtiodev +virtiodev virtio-setup-vd + +\ +\ Support methods. + +: shutdown  ( -- ) +   initialized? 0= IF EXIT THEN +   virtiodev virtio-fs-shutdown +   virtfs-rx-buffer VIRTFS-BUF-SIZE free-mem +   virtfs-tx-buffer VIRTFS-BUF-SIZE free-mem +   FALSE to initialized? +; + +: init  ( -- success ) +   VIRTFS-BUF-SIZE alloc-mem to virtfs-rx-buffer +   VIRTFS-BUF-SIZE alloc-mem to virtfs-tx-buffer +    +   virtiodev			( dev ) +   virtfs-tx-buffer		( dev tx ) +   virtfs-rx-buffer		( reg tx rx ) +   VIRTFS-BUF-SIZE		( reg tx rx size )    +   virtio-fs-init		( success ) +    +   dup IF +      TRUE to initialized? +      ['] shutdown add-quiesce-xt +   THEN +; + +\ +\ Standard network interface. + +: open  ( -- okay? ) +   open 0= IF false EXIT THEN +   initialized? 0= IF +      init 0= IF false EXIT THEN +   THEN    +   true +; + +: load ( addr -- len ) +   virtiodev swap		( dev addr )    +   my-args   			( dev addr str strlen ) +   1 +		\ hack to make the following allocate 1 more byte +   \-to-/	\ convert path elements +   1 - 2dup + 0 swap c! drop +   virtio-fs-load		( length ) +; + +: close  ( -- ) +   initialized? IF +      shutdown +   THEN +   close +; + +: ping ( -- ) +   cr s" ping not supported for this device" type cr cr +; + + +: (set-alias) +    " virtfs" find-alias 0= IF +        " virtfs" get-node node>path set-alias +    ELSE +        drop +    THEN +; + +\ +\ Init the module. + +(set-alias) diff --git a/roms/SLOF/board-qemu/slof/virtio-net.fs b/roms/SLOF/board-qemu/slof/virtio-net.fs new file mode 100644 index 00000000..412b34fa --- /dev/null +++ b/roms/SLOF/board-qemu/slof/virtio-net.fs @@ -0,0 +1,96 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ ." Populating " pwd cr + +s" network" device-type + +INSTANCE VARIABLE obp-tftp-package + +/vd-len BUFFER: virtiodev +virtiodev virtio-setup-vd +0 VALUE virtio-net-priv +0 VALUE open-count + +: open  ( -- okay? ) +   open-count 0= IF +      open IF +         \ my-unit 1 rtas-set-tce-bypass +         s" local-mac-address" get-node get-property not IF +            virtiodev virtio-net-open dup not IF ." virtio-net-open failed" EXIT THEN +            drop TO virtio-net-priv +         THEN +         true +      ELSE +         false +      THEN +   ELSE +      true +   THEN +   my-args s" obp-tftp" $open-package obp-tftp-package ! +   open-count 1 + to open-count +; + + +: close  ( -- ) +    open-count 0> IF +      open-count 1 - dup to open-count +      0= IF +         virtio-net-priv virtio-net-close +         \ my-unit 0 rtas-set-tce-bypass +         close +      THEN +   THEN +   s" close" obp-tftp-package @ $call-method +; + +: read ( buf len -- actual ) +   dup IF +      virtio-net-read +   ELSE +      nip +   THEN +; + +: write ( buf len -- actual ) +   dup IF +      virtio-net-write +   ELSE +      nip +   THEN +; + +: load  ( addr -- len ) +   s" load" obp-tftp-package @ $call-method  +; + +: ping  ( -- ) +   s" ping" obp-tftp-package @ $call-method +; + +\ Set up MAC address from config virtqueue +6 BUFFER: local-mac +: setup-mac  ( -- ) +   6 0 DO +      virtiodev i 1 virtio-get-config +      local-mac i + c! +   LOOP +   local-mac 6 encode-bytes  s" local-mac-address"  property +; +setup-mac + +: setup-alias  ( -- ) +   " net" get-next-alias ?dup IF +      get-node node>path set-alias +   THEN +; +setup-alias diff --git a/roms/SLOF/board-qemu/slof/virtio-scsi.fs b/roms/SLOF/board-qemu/slof/virtio-scsi.fs new file mode 100644 index 00000000..ca5fb13a --- /dev/null +++ b/roms/SLOF/board-qemu/slof/virtio-scsi.fs @@ -0,0 +1,232 @@ +\ ***************************************************************************** +\ * Copyright (c) 2012 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +." Populating " pwd cr + +FALSE CONSTANT virtio-scsi-debug + +2 encode-int s" #address-cells" property +0 encode-int s" #size-cells" property + +: decode-unit 2 hex64-decode-unit ; +: encode-unit 2 hex64-encode-unit ; + +FALSE VALUE initialized? + +/vd-len BUFFER: virtiodev +virtiodev virtio-setup-vd + +STRUCT \ virtio-scsi-config +    /l FIELD vs-cfg>num-queues +    /l FIELD vs-cfg>seg-max +    /l FIELD vs-cfg>max-sectors +    /l FIELD vs-cfg>cmd-per-lun +    /l FIELD vs-cfg>event-info-size +    /l FIELD vs-cfg>sense_size +    /l FIELD vs-cfg>cdb-size +    /w FIELD vs-cfg>max-channel +    /w FIELD vs-cfg>max-target +    /l FIELD vs-cfg>max-lun +CONSTANT vs-cfg-length + +STRUCT \ virtio-scsi-req +    8  FIELD vs-req>lun +    8  FIELD vs-req>tag +    /c FIELD vs-req>task-attr +    /c FIELD vs-req>prio +    /c FIELD vs-req>crn +    20 FIELD vs-req>cdb +CONSTANT vs-req-length + +STRUCT \ virtio-scsi-resp +    /l FIELD vs-rsp>sense-len +    /l FIELD vs-rsp>residual +    /w FIELD vs-rsp>status-qualifier +    /c FIELD vs-rsp>status +    /c FIELD vs-rsp>response +    60 FIELD vs-rsp>sense +CONSTANT vs-rsp-length + +CREATE vs-req vs-req-length allot +CREATE vs-rsp vs-rsp-length allot + +scsi-open + +\ ----------------------------------------------------------- +\ Perform SCSI commands +\ ----------------------------------------------------------- + +0 INSTANCE VALUE current-target + +\ SCSI command. We do *NOT* implement the "standard" execute-command +\ because that doesn't have a way to return the sense buffer back, and +\ we do have auto-sense with some hosts. Instead we implement a made-up +\ do-scsi-command. +\ +\ Note: stat is -1 for "hw error" (ie, error queuing the command or +\ getting the response). +\ +\ A sense buffer is returned whenever the status is non-0 however +\ if sense-len is 0 then no sense data is actually present +\ + +: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... ) +                       ( ... [ sense-buf sense-len ] stat ) +    \ Cleanup virtio request and response +    vs-req vs-req-length erase +    vs-rsp vs-rsp-length erase + +    \ Populate the request +    current-target vs-req vs-req>lun x! +    vs-req vs-req>cdb swap move + +    \ Send it +    vs-req vs-rsp virtiodev +    virtio-scsi-send + +    0 <> IF +        ." VIRTIO-SCSI: Queuing failure !" cr +        0 0 -1 EXIT +    THEN + +    \ Check virtio response +    vs-rsp vs-rsp>response c@ CASE +        0 OF ENDOF			\ Good +        5 OF drop 0 0 8 EXIT ENDOF	\ Busy +        dup OF 0 0 -1 EXIT ENDOF	\ Anything else -> HW error +    ENDCASE + +    \ Other error status +    vs-rsp vs-rsp>status c@ dup 0<> IF +        vs-rsp vs-rsp>sense-len l@ dup 0= IF +            \ This relies on auto-sense from qemu... if that isn't always the +            \ case we should request sense here +            ." VIRTIO-SCSI: No sense data" cr +	    0 EXIT +        THEN +        vs-rsp vs-rsp>sense swap +        virtio-scsi-debug IF +            over scsi-get-sense-data +            ." VIRTIO-SCSI: Sense key [ " dup . ." ] " .sense-text +	    ."  ASC,ASCQ: " . . cr +        THEN +       rot +    THEN     +; + +\ -------------------------------- +\ Include the generic host helpers +\ -------------------------------- + +" scsi-host-helpers.fs" included + +\ FIXME: Check max transfer coming from virtio config +: max-transfer ( -- n ) +    10000 \ Larger value seem to have problems with some CDROMs +; + +\ ----------------------------------------------------------- +\ SCSI scan at boot and child device support +\ ----------------------------------------------------------- + +\ We use SRP luns of the form 01000000 | (target << 16) | lun +\ in the top 32 bits of the 64-bit LUN +: (set-target) +    to current-target +; + +: dev-generate-srplun ( target lun-id -- srplun ) +    swap 0100 or 10 << or 20 << +; + +\ We obtain here a unit address on the stack, since our #address-cells +\ is 2, the 64-bit srplun is split in two cells that we need to join +\ +\ Note: This diverges a bit from the original OF scsi spec as the two +\ cells are the 2 words of a 64-bit SRP LUN +: set-address ( srplun.lo srplun.hi -- ) +    lxjoin (set-target) +; + +100 CONSTANT #target +: dev-max-target ( -- #target ) +    #target +; + +" scsi-probe-helpers.fs" included + +scsi-close        \ no further scsi words required + +0 VALUE queue-control-addr +0 VALUE queue-event-addr +0 VALUE queue-cmd-addr + +: setup-virt-queues +    \ add 3 queues 0-controlq, 1-eventq, 2-cmdq +    \ fixme: do we need to find more than the above 3 queues if exists +    virtiodev 0 virtio-get-qsize virtio-vring-size +    alloc-mem to queue-control-addr +    virtiodev 0 queue-control-addr virtio-set-qaddr + +    virtiodev 1 virtio-get-qsize virtio-vring-size +    alloc-mem to queue-event-addr +    virtiodev 1 queue-event-addr virtio-set-qaddr + +    virtiodev 2 virtio-get-qsize virtio-vring-size +    alloc-mem to queue-cmd-addr +    virtiodev 2 queue-cmd-addr virtio-set-qaddr +; + +\ Set scsi alias if none is set yet +: setup-alias +    s" scsi" find-alias 0= IF +	s" scsi" get-node node>path set-alias +    ELSE +	drop +    THEN +; + +: shutdown ( -- ) +    initialized? IF +       my-phandle node>path open-dev ?dup IF +          virtiodev virtio-scsi-shutdown +          close-dev +       THEN +       FALSE to initialized? +    THEN +; + +: virtio-scsi-init-and-scan  ( -- ) +    \ Create instance for scanning: +    0 0 get-node open-node ?dup 0= IF ." exiting " cr EXIT THEN +    my-self >r +    dup to my-self +    \ Scan the VSCSI bus: +    virtiodev virtio-scsi-init +    0= IF +	setup-virt-queues +	scsi-find-disks +	setup-alias +	TRUE to initialized? +	['] shutdown add-quiesce-xt +    THEN +    \ Close the temporary instance: +    close-node +    r> to my-self +; + +: virtio-scsi-add-disk +    " scsi-disk.fs" included +; + +virtio-scsi-add-disk +virtio-scsi-init-and-scan diff --git a/roms/SLOF/board-qemu/slof/virtio.fs b/roms/SLOF/board-qemu/slof/virtio.fs new file mode 100644 index 00000000..818c1320 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/virtio.fs @@ -0,0 +1,35 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ *     IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ This struct must match "struct virtio_device" in virtio.h! +STRUCT +   /n FIELD vd>base +   /l FIELD vd>type +CONSTANT /vd-len + + +\ Initialize virtiodev structure for the current node +: virtio-setup-vd  ( vdstruct -- ) +   >r +   \ Does it have a "class-code" property? If yes, assume we're a PCI device +   s" class-code" get-node get-property 0= IF +      \ Set up for PCI device interface +      2drop +      s" 10 config-l@ translate-my-address 3 not AND" evaluate +      ( io-base ) r@ vd>base ! +      0 r@ vd>type l! +   ELSE +      ." unsupported virtio interface!" cr +      1 r@ vd>type l! +   THEN +   r> drop +;  | 
