diff options
Diffstat (limited to 'qemu/roms/SLOF/board-qemu')
51 files changed, 5032 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/board-qemu/Makefile b/qemu/roms/SLOF/board-qemu/Makefile new file mode 100644 index 000000000..29ee016ad --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/Makefile.dirs b/qemu/roms/SLOF/board-qemu/Makefile.dirs new file mode 100644 index 000000000..1493d3bf1 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/config b/qemu/roms/SLOF/board-qemu/config new file mode 100644 index 000000000..f1940914f --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/include/hw.h b/qemu/roms/SLOF/board-qemu/include/hw.h new file mode 100644 index 000000000..27117c3f3 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/include/nvramlog.h b/qemu/roms/SLOF/board-qemu/include/nvramlog.h new file mode 100644 index 000000000..d13025596 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/include/product.h b/qemu/roms/SLOF/board-qemu/include/product.h new file mode 100644 index 000000000..819d6eda1 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/include/southbridge.h b/qemu/roms/SLOF/board-qemu/include/southbridge.h new file mode 100644 index 000000000..1cdb422c0 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/llfw/Cboot.S b/qemu/roms/SLOF/board-qemu/llfw/Cboot.S new file mode 100644 index 000000000..d22f3c934 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/llfw/Makefile b/qemu/roms/SLOF/board-qemu/llfw/Makefile new file mode 100644 index 000000000..c83f21e3a --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/llfw/board_io.S b/qemu/roms/SLOF/board-qemu/llfw/board_io.S new file mode 100644 index 000000000..7d572ab18 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/llfw/stage2.c b/qemu/roms/SLOF/board-qemu/llfw/stage2.c new file mode 100644 index 000000000..ef6ea355a --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/llfw/stage2.h b/qemu/roms/SLOF/board-qemu/llfw/stage2.h new file mode 100644 index 000000000..9ce3c8203 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/llfw/stage2.lds b/qemu/roms/SLOF/board-qemu/llfw/stage2.lds new file mode 100644 index 000000000..e060dd189 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/llfw/stage2_head.S b/qemu/roms/SLOF/board-qemu/llfw/stage2_head.S new file mode 100644 index 000000000..c56b117ce --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/llfw/startup.S b/qemu/roms/SLOF/board-qemu/llfw/startup.S new file mode 100644 index 000000000..bbd3ce3ac --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/llfw/version.S b/qemu/roms/SLOF/board-qemu/llfw/version.S new file mode 100644 index 000000000..f0a778abe --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/romfs/boot_rom.ffs b/qemu/roms/SLOF/board-qemu/romfs/boot_rom.ffs new file mode 100644 index 000000000..3cdb7d348 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/.gitignore b/qemu/roms/SLOF/board-qemu/slof/.gitignore new file mode 100644 index 000000000..55268aa6a --- /dev/null +++ b/qemu/roms/SLOF/board-qemu/slof/.gitignore @@ -0,0 +1 @@ +OF.ffs diff --git a/qemu/roms/SLOF/board-qemu/slof/Makefile b/qemu/roms/SLOF/board-qemu/slof/Makefile new file mode 100644 index 000000000..283f77d32 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/OF.fs b/qemu/roms/SLOF/board-qemu/slof/OF.fs new file mode 100644 index 000000000..561d89225 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/copyright-oss.fs b/qemu/roms/SLOF/board-qemu/slof/copyright-oss.fs new file mode 100644 index 000000000..e45b19403 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/dev-null.fs b/qemu/roms/SLOF/board-qemu/slof/dev-null.fs new file mode 100644 index 000000000..d0ffad6b9 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/e1k.fs b/qemu/roms/SLOF/board-qemu/slof/e1k.fs new file mode 100644 index 000000000..51855be82 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/fdt.fs b/qemu/roms/SLOF/board-qemu/slof/fdt.fs new file mode 100644 index 000000000..8d4635f30 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/header.fs b/qemu/roms/SLOF/board-qemu/slof/header.fs new file mode 100644 index 000000000..8bc17a189 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/helper.fs b/qemu/roms/SLOF/board-qemu/slof/helper.fs new file mode 100644 index 000000000..96da49894 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/hvterm.fs b/qemu/roms/SLOF/board-qemu/slof/hvterm.fs new file mode 100644 index 000000000..98c144582 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-aliases.fs b/qemu/roms/SLOF/board-qemu/slof/pci-aliases.fs new file mode 100644 index 000000000..9ce519da1 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-capabilities.fs b/qemu/roms/SLOF/board-qemu/slof/pci-capabilities.fs new file mode 100644 index 000000000..ef8c7b0d4 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-device_1013_00b8.fs b/qemu/roms/SLOF/board-qemu/slof/pci-device_1013_00b8.fs new file mode 100644 index 000000000..c3ac2ec41 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs b/qemu/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs new file mode 100644 index 000000000..a5c3584f9 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-device_1af4_1000.fs b/qemu/roms/SLOF/board-qemu/slof/pci-device_1af4_1000.fs new file mode 100644 index 000000000..ac18e0efb --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-device_1af4_1001.fs b/qemu/roms/SLOF/board-qemu/slof/pci-device_1af4_1001.fs new file mode 100644 index 000000000..fb2463467 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-device_1af4_1004.fs b/qemu/roms/SLOF/board-qemu/slof/pci-device_1af4_1004.fs new file mode 100644 index 000000000..9c1089ac8 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-device_1af4_1009.fs b/qemu/roms/SLOF/board-qemu/slof/pci-device_1af4_1009.fs new file mode 100644 index 000000000..03964a6db --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-device_8086_100e.fs b/qemu/roms/SLOF/board-qemu/slof/pci-device_8086_100e.fs new file mode 100644 index 000000000..8f279a254 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-interrupts.fs b/qemu/roms/SLOF/board-qemu/slof/pci-interrupts.fs new file mode 100644 index 000000000..e11b77932 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/pci-phb.fs b/qemu/roms/SLOF/board-qemu/slof/pci-phb.fs new file mode 100644 index 000000000..a8fb7ca5e --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/qemu-bootlist.fs b/qemu/roms/SLOF/board-qemu/slof/qemu-bootlist.fs new file mode 100644 index 000000000..4778e1629 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/rtas-nvram.fs b/qemu/roms/SLOF/board-qemu/slof/rtas-nvram.fs new file mode 100644 index 000000000..fdebfb239 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/rtas.fs b/qemu/roms/SLOF/board-qemu/slof/rtas.fs new file mode 100644 index 000000000..2e10b0a50 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/tree.fs b/qemu/roms/SLOF/board-qemu/slof/tree.fs new file mode 100644 index 000000000..4aba4c53f --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/version.S b/qemu/roms/SLOF/board-qemu/slof/version.S new file mode 100644 index 000000000..9aa2a94fc --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/vio-hvterm.fs b/qemu/roms/SLOF/board-qemu/slof/vio-hvterm.fs new file mode 100644 index 000000000..3519751e6 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/vio-veth.fs b/qemu/roms/SLOF/board-qemu/slof/vio-veth.fs new file mode 100644 index 000000000..3c8f489fe --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/vio-vscsi.fs b/qemu/roms/SLOF/board-qemu/slof/vio-vscsi.fs new file mode 100644 index 000000000..f2d4c6fcc --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/virtio-block.fs b/qemu/roms/SLOF/board-qemu/slof/virtio-block.fs new file mode 100644 index 000000000..ea388fb00 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/virtio-fs.fs b/qemu/roms/SLOF/board-qemu/slof/virtio-fs.fs new file mode 100644 index 000000000..8632b465f --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/virtio-net.fs b/qemu/roms/SLOF/board-qemu/slof/virtio-net.fs new file mode 100644 index 000000000..412b34fa6 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/virtio-scsi.fs b/qemu/roms/SLOF/board-qemu/slof/virtio-scsi.fs new file mode 100644 index 000000000..ca5fb13aa --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/board-qemu/slof/virtio.fs b/qemu/roms/SLOF/board-qemu/slof/virtio.fs new file mode 100644 index 000000000..818c1320e --- /dev/null +++ b/qemu/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 +; |