diff options
70 files changed, 3667 insertions, 59 deletions
diff --git a/.target b/.target deleted file mode 100644 index 5356a3d..0000000 --- a/.target +++ /dev/null @@ -1 +0,0 @@ -js2x diff --git a/board-js2x/config b/board-js2x/config index addaf8e..3f6a6c8 100644 --- a/board-js2x/config +++ b/board-js2x/config @@ -1,6 +1,6 @@ BOARD=js2x TARG=ppc64 -FLAG="-DBIOSEMU" +export FLAG="-DBIOSEMU" export CPUARCH=ppc970 export CPUARCHDEF=-DCPU_PPC970 export SNK_BIOSEMU_APPS=1 diff --git a/board-qemu/Makefile b/board-qemu/Makefile new file mode 100644 index 0000000..b67ee24 --- /dev/null +++ b/board-qemu/Makefile @@ -0,0 +1,76 @@ +# ***************************************************************************** +# * 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 net_veth stage1 + +SUBDIRS = slof +COMMON_LIBS = libc libbootmsg libbases libnvram libelf libhvcall + +all: $(BOARD_TARGETS) subdirs 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) + +stage1: common-libs + @echo " ====== Building llfw ======" + make -C llfw RELEASE=-DRELEASE=\"\\\"$(RELEASE)\\\"\" + +net_veth: common-libs + @echo " ====== Building veth ======" + make -C veth + +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 + make -C veth 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 + make -C veth distclean + +.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/board-qemu/Makefile.dirs b/board-qemu/Makefile.dirs new file mode 100644 index 0000000..1493d3b --- /dev/null +++ b/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/board-qemu/config b/board-qemu/config new file mode 100644 index 0000000..63976a0 --- /dev/null +++ b/board-qemu/config @@ -0,0 +1,7 @@ +BOARD=qemu +TARG=ppc64 +export FLAG="-DDISABLE_NVRAM" +export CPUARCH=ppcp7 +export CPUARCHDEF=-DCPU_PPCP7 +#export SNK_BIOSEMU_APPS=1 +FLASH_SIZE=8388608 diff --git a/board-qemu/include/hw.h b/board-qemu/include/hw.h new file mode 100644 index 0000000..27117c3 --- /dev/null +++ b/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/board-qemu/include/nvramlog.h b/board-qemu/include/nvramlog.h new file mode 100644 index 0000000..fef7661 --- /dev/null +++ b/board-qemu/include/nvramlog.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * 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 0x2000 // 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 0x500 // 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 MAMBO_NVRAM_BASE 0x100000 // NVRAM Base for MAMBO + #define NVRAM_EMPTY_PATTERN 0x0000000000000000 // Pattern (64-bit) used to overwrite NVRAM + +#endif diff --git a/board-qemu/include/product.h b/board-qemu/include/product.h new file mode 100644 index 0000000..819d6ed --- /dev/null +++ b/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/board-qemu/include/southbridge.h b/board-qemu/include/southbridge.h new file mode 100644 index 0000000..3ca4e04 --- /dev/null +++ b/board-qemu/include/southbridge.h @@ -0,0 +1,20 @@ +/****************************************************************************** + * 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 NVRAM_LENGTH 0x10000 +#define FLASH_LENGTH 0 +#define SB_MAILBOX_adr 0 + +#define SECONDARY_CPUS_STOPPED diff --git a/board-qemu/llfw/Cboot.S b/board-qemu/llfw/Cboot.S new file mode 100644 index 0000000..d22f3c9 --- /dev/null +++ b/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/board-qemu/llfw/Makefile b/board-qemu/llfw/Makefile new file mode 100644 index 0000000..f124a3b --- /dev/null +++ b/board-qemu/llfw/Makefile @@ -0,0 +1,56 @@ +# ***************************************************************************** +# * 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 $(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 boot_abort.o romfs.o io_generic.o board_io.o +STG1OBJ += stage2_head.o stage2.o comlib.o romfs_wrap.o nvramlog.o + +all: stage1.bin Cboot.o + +stage1.bin: $(STG1OBJ) $(LIBCMNDIR)/libelf.a $(LIBCMNDIR)/libc.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/board-qemu/llfw/board_io.S b/board-qemu/llfw/board_io.S new file mode 100644 index 0000000..7d572ab --- /dev/null +++ b/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/board-qemu/llfw/stage2.c b/board-qemu/llfw/stage2.c new file mode 100644 index 0000000..59b0296 --- /dev/null +++ b/board-qemu/llfw/stage2.c @@ -0,0 +1,186 @@ +/****************************************************************************** + * 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> + +#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]; + +void c_memInit(uint64_t r3, uint64_t r4); + +void proceedInterrupt(); + +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; +} + +uint64_t get_dec(void) +{ + return 0xdeadaffe; +} + +void set_dec(uint64_t val) +{ +} + +uint64_t tb_frequency(void) +{ + return 0; +} + +static void load_file(uint64_t destAddr, char *name, uint64_t maxSize, + uint64_t romfs_base) +{ + uint64_t *src, *dest, 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); + dest = (uint64_t *) destAddr; + src = (uint64_t *) fileInfo.addr_data; + flush_cache((void *) destAddr, fileInfo.size_data); +} + +/*************************************************************************** + * 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; + // romfs header values + struct stH *header = (struct stH *) (start_addr + 0x28); + uint64_t flashlen = 0; + unsigned long ofw_addr[2]; + int rc; + + flashlen = header->flashlen; + + romfs_base = 0x10000000 - 0x400000; + if (romfs_base) + 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]); + rc = load_elf_file((void *)fileInfo.addr_data, ofw_addr); + 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]; + /* ePAPR 0.5 + * r3 = R3 Effective address of the device tree image. Note: this + * address must be 8-byte aligned in memory. + * r4 = implementation dependent + * r5 = 0 + * r6 = 0x65504150 -- ePAPR magic value-to distinguish from + * non-ePAPR-compliant firmware + * r7 = implementation dependent + */ + asm volatile("isync; sync;" : : : "memory"); + ofw_start(fdt_addr, romfs_base, 0, 0, 0); + asm volatile("isync; sync;" : : : "memory"); + // never return +} diff --git a/board-qemu/llfw/stage2.h b/board-qemu/llfw/stage2.h new file mode 100644 index 0000000..9ce3c82 --- /dev/null +++ b/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/board-qemu/llfw/stage2.lds b/board-qemu/llfw/stage2.lds new file mode 100644 index 0000000..4012ea5 --- /dev/null +++ b/board-qemu/llfw/stage2.lds @@ -0,0 +1,55 @@ +/****************************************************************************** + * 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 { + .text : { + *(.text) + } + + . = 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/board-qemu/llfw/stage2_head.S b/board-qemu/llfw/stage2_head.S new file mode 100644 index 0000000..c56b117 --- /dev/null +++ b/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/board-qemu/llfw/startup.S b/board-qemu/llfw/startup.S new file mode 100644 index 0000000..5882164 --- /dev/null +++ b/board-qemu/llfw/startup.S @@ -0,0 +1,258 @@ +/****************************************************************************** + * 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 "termctrl.h" +#include <product.h> +#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 + 0x160)(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 + + /* give live sign *****************************/ + 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 + bl io_print + + /* 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/board-qemu/romfs/boot_rom.ffs b/board-qemu/romfs/boot_rom.ffs new file mode 100644 index 0000000..385a08d --- /dev/null +++ b/board-qemu/romfs/boot_rom.ffs @@ -0,0 +1,21 @@ +# ***************************************************************************** +# * 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 +net_veth board-qemu/veth/net_veth.bin 0 0 diff --git a/board-qemu/slof/Makefile b/board-qemu/slof/Makefile new file mode 100644 index 0000000..842767f --- /dev/null +++ b/board-qemu/slof/Makefile @@ -0,0 +1,96 @@ +# ***************************************************************************** +# * 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: Makefile.dep OF.ffs paflof $(SLOFCMNDIR)/xvect.bin + +CPPFLAGS = -I$(LIBCMNDIR)/libbootmsg -I$(LIBCMNDIR)/libhvcall \ + -I$(LIBCMNDIR)/libnvram +SLOF_LIBS = $(LIBCMNDIR)/libbootmsg.a $(LIBCMNDIR)/libhvcall.a \ + $(LIBCMNDIR)/libnvram.a +BOARD_SLOF_IN = \ + $(LIBCMNDIR)/libhvcall/hvcall.in \ + $(LIBCMNDIR)/libbootmsg/bootmsg.in \ + $(LIBCMNDIR)/libnvram/libnvram.in \ + $(LIBCMNDIR)/libbases/libbases.in +BOARD_SLOF_CODE = $(BOARD_SLOF_IN:%.in=%.code) + +include $(SLOFCMNDIR)/Makefile.inc + +FPPINCLUDES = -I. -I$(SLOFCMNDIR)/fs -I$(SLOFCMNDIR) + +# FCode Evaluator files for the ROM fs: +FCODE_FFS_FILES = \ + $(SLOFCMNDIR)/fs/fcode/core.fs \ + $(SLOFCMNDIR)/fs/fcode/evaluator.fs \ + $(SLOFCMNDIR)/fs/fcode/big.fs \ + $(SLOFCMNDIR)/fs/fcode/tokens.fs \ + $(SLOFCMNDIR)/fs/fcode/1275.fs + + +USB_FFS_FILES = \ + $(SLOFCMNDIR)/fs/devices/pci-class_0c.fs \ + $(SLOFCMNDIR)/fs/usb/usb-ohci.fs \ + $(SLOFCMNDIR)/fs/usb/usb-support.fs \ + $(SLOFCMNDIR)/fs/usb/usb-hub.fs \ + $(SLOFCMNDIR)/fs/usb/usb-enumerate.fs \ + $(SLOFCMNDIR)/fs/usb/usb-storage.fs \ + $(SLOFCMNDIR)/fs/usb/usb-storage-support.fs \ + $(SLOFCMNDIR)/fs/usb/usb-storage-wrapper.fs \ + $(SLOFCMNDIR)/fs/usb/usb-keyboard.fs \ + $(SLOFCMNDIR)/fs/usb/usb-kbd-device-support.fs \ + $(SLOFCMNDIR)/fs/usb/usb-mouse.fs \ + $(SLOFCMNDIR)/fs/scsi-support.fs + +VIO_FFS_FILES = \ + $(SLOFBRDDIR)/vio-hvterm.fs \ + $(SLOFBRDDIR)/vio-vscsi.fs \ + $(SLOFBRDDIR)/vio-vscsi-device.fs \ + $(SLOFBRDDIR)/vio-veth.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/generic-disk.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 \ + $(SLOFBRDDIR)/default-font.bin \ + $(FCODE_FFS_FILES) + +# Uncomment the following line to enable the USB code: +OF_FFS_FILES += $(USB_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/board-qemu/slof/OF.fs b/board-qemu/slof/OF.fs new file mode 100644 index 0000000..ede41e7 --- /dev/null +++ b/board-qemu/slof/OF.fs @@ -0,0 +1,160 @@ +\ ***************************************************************************** +\ * 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" + +\ 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 +; + +080 cp + +100 cp + +\ Input line editing. +#include "accept.fs" + +120 cp + +#include "dump.fs" + +cistack ciregs >r1 ! \ kernel wants a stack :-) + +#include "romfs.fs" + +140 cp + +200 cp + +201 cp +#include <slof-logo.fs> +#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> + +280 cp + +2c0 cp + +2e0 cp + +#include <quiesce.fs> + +300 cp + +#include <usb/usb-static.fs> + +320 cp + +#include <scsi-loader.fs> + +340 cp + +360 cp + +#include "fdt.fs" + +370 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> + +8b0 cp + +8e0 cp + +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/board-qemu/slof/copyright-oss.fs b/board-qemu/slof/copyright-oss.fs new file mode 100644 index 0000000..e45b194 --- /dev/null +++ b/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/board-qemu/slof/fdt.fs b/board-qemu/slof/fdt.fs new file mode 100644 index 0000000..43b97fe --- /dev/null +++ b/board-qemu/slof/fdt.fs @@ -0,0 +1,251 @@ +\ ***************************************************************************** +\ * 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 + +\ 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 +fdt-start +dup dup >fdth_struct_off l@ + value fdt-struct +dup dup >fdth_string_off l@ + value fdt-strings +drop + +\ Dump fdt header for all to see and check FDT validity +: fdt-check-header ( -- ) + fdt-start 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 +; + +\ Lookup a string by index +: fdt-fetch-string ( index -- $string) + fdt-strings + dup from-cstring +; + +: fdt-create-dec s" decode-unit" $CREATE , DOES> @ hex-decode-unit ; +: fdt-create-enc s" encode-unit" $CREATE , DOES> @ hex-encode-unit ; + +\ 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 unit address + 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 ) + encode-bytes rot ( a1 s pa ps i) + fdt-fetch-string ( a1 s pa ps $pn ) + 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 + " /memory" 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 + MIN-RAM-SIZE swap release + 2drop device-end +; +fdt-parse-memory + + +\ Claim fdt memory and reserve map +: fdt-claim-reserve + fdt-start + 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 + +\ Remaining bits from root.fs + +defer (client-exec) +defer client-exec + +\ defined in slof/fs/client.fs +defer callback +defer continue-client + +: set-chosen ( prop len name len -- ) + s" /chosen" find-node set-property ; + +: get-chosen ( name len -- [ prop len ] success ) + s" /chosen" find-node get-property 0= ; + +" /" find-device + +new-device + s" aliases" device-name +finish-device + +new-device + s" options" device-name +finish-device + +new-device + s" openprom" device-name + s" BootROM" device-type +finish-device + +new-device +#include <packages.fs> +finish-device + +: open true ; +: close ; + +device-end + diff --git a/board-qemu/slof/header.fs b/board-qemu/slof/header.fs new file mode 100644 index 0000000..0519cc9 --- /dev/null +++ b/board-qemu/slof/header.fs @@ -0,0 +1,22 @@ +\ ***************************************************************************** +\ * 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 +ff8f9000 CONSTANT sec-nvram-base \ save area from phype.... not really known +2000 CONSTANT sec-nvram-size + +nvram-base 20000 + CONSTANT nvram-log-be1-base diff --git a/board-qemu/slof/helper.fs b/board-qemu/slof/helper.fs new file mode 100644 index 0000000..96da498 --- /dev/null +++ b/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/board-qemu/slof/hvterm.fs b/board-qemu/slof/hvterm.fs new file mode 100644 index 0000000..2827e25 --- /dev/null +++ b/board-qemu/slof/hvterm.fs @@ -0,0 +1,26 @@ +\ ***************************************************************************** +\ * 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. + +: hvterm-emit hv-putchar ; +: hvterm-key? hv-haschar ; +: hvterm-key BEGIN hvterm-key? UNTIL 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/board-qemu/slof/qemu-bootlist.fs b/board-qemu/slof/qemu-bootlist.fs new file mode 100644 index 0000000..6b52b97 --- /dev/null +++ b/board-qemu/slof/qemu-bootlist.fs @@ -0,0 +1,38 @@ +\ ***************************************************************************** +\ * 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 + +: qemu-read-bootlist ( -- ) + 0 0 set-boot-device + + \ check nvram + " boot-device" evaluate swap drop 0 <> IF EXIT THEN + + \ check qemu boot list + " qemu,boot-device" get-chosen not IF 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-device ENDOF + [char] d OF " cdrom" add-boot-device ENDOF + [char] n OF " net" add-boot-device ENDOF + ENDCASE cr + LOOP + drop +; + +' qemu-read-bootlist to read-bootlist diff --git a/board-qemu/slof/rtas.fs b/board-qemu/slof/rtas.fs new file mode 100644 index 0000000..d8a6c58 --- /dev/null +++ b/board-qemu/slof/rtas.fs @@ -0,0 +1,126 @@ +\ ***************************************************************************** +\ * 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 + +4d0 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 + +4d1 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 + + device-end +; +find-qemu-rtas + +4d2 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 +; + +: rtas-start-cpu ( pid loc r3 -- status ) + " start-cpu" rtas-get-token rtas-cb rtas>token l! + 3 rtas-cb rtas>nargs l! + 1 rtas-cb rtas>nret l! + rtas-cb rtas>args2 l! + rtas-cb rtas>args1 l! + rtas-cb rtas>args0 l! + 0 rtas-cb rtas>args3 l! + enter-rtas + rtas-cb rtas>args3 l@ +; + +: 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 +; + +: of-start-cpu rtas-start-cpu ; + +\ Methods of the rtas node proper +rtas-node set-node + +: open true ; +: close ; + +: instantiate-rtas ( adr -- entry ) + dup rtas-base swap rtas-size move + rtas-entry rtas-base - + +; + +device-end + +4d8 cp diff --git a/board-qemu/slof/tree.fs b/board-qemu/slof/tree.fs new file mode 100644 index 0000000..c2ab824 --- /dev/null +++ b/board-qemu/slof/tree.fs @@ -0,0 +1,150 @@ +\ ***************************************************************************** +\ * 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 + +0 value puid + +440 cp + +480 cp + +\ The root of the device tree and some of its kids. +" /" find-device + +" QEMU" encode-string s" model" property + +2 encode-int s" #address-cells" property +2 encode-int s" #size-cells" property + +\ Yaboot is stupid. Without this, it can't/won't find /etc/yaboot.conf. +s" chrp" device-type + +\ 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 + +\ Grab rtas from qemu +#include "rtas.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 + 2drop + THEN + peer + REPEAT drop + + device-end +; + +\ Now do it +populate-vios + +580 cp + +5a0 cp + +600 cp + +\ 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" 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> + +" hvterm" find-alias IF drop + " hvterm" io +THEN diff --git a/board-qemu/slof/vio-hvterm.fs b/board-qemu/slof/vio-hvterm.fs new file mode 100644 index 0000000..32b2a59 --- /dev/null +++ b/board-qemu/slof/vio-hvterm.fs @@ -0,0 +1,32 @@ +\ ***************************************************************************** +\ * 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 type ; + +: read ( adr len -- actual ) + 0= IF drop 0 EXIT THEN + hvterm-key? 0= IF 0 swap c! -2 EXIT THEN + hvterm-key swap c! 1 +; + +: setup-alias + " hvterm" find-alias 0= IF + " hvterm" get-node node>path set-alias + ELSE THEN +; + +setup-alias diff --git a/board-qemu/slof/vio-veth.fs b/board-qemu/slof/vio-veth.fs new file mode 100644 index 0000000..0da0c61 --- /dev/null +++ b/board-qemu/slof/vio-veth.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 + +" network" device-type + +INSTANCE VARIABLE obp-tftp-package +: open ( -- okay? ) + my-unit 1 rtas-set-tce-bypass + my-args s" obp-tftp" $open-package obp-tftp-package ! true +; + +: close ( -- ) + s" close" obp-tftp-package @ $call-method + my-unit 0 rtas-set-tce-bypass +; + +: load ( addr -- len ) + s" load" obp-tftp-package @ $call-method +; + +: ping ( -- ) + s" ping" obp-tftp-package @ $call-method +; + +: setup-alias + " net" find-alias 0= IF + " net" get-node node>path set-alias + ELSE THEN +; +setup-alias diff --git a/board-qemu/slof/vio-vscsi-device.fs b/board-qemu/slof/vio-vscsi-device.fs new file mode 100644 index 0000000..1c48706 --- /dev/null +++ b/board-qemu/slof/vio-vscsi-device.fs @@ -0,0 +1,72 @@ +\ ***************************************************************************** +\ * 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 +\ ****************************************************************************/ + +\ Create new VSCSI child device +\ ( lun id $name is_cdrom -- ) + +\ Create device +new-device + +VALUE is_cdrom + +2swap ( $name lun id ) + +\ Set reg & unit +2dup set-unit encode-phys " reg" property + +\ Set name +2dup device-name + +2dup find-alias 0= IF + get-node node>path set-alias +ELSE 2drop THEN + +s" block" device-type + +\ Required interface for deblocker + +0 INSTANCE VALUE block-size +0 INSTANCE VALUE max-block-num +0 INSTANCE VALUE max-transfer + +: read-blocks ( addr block# #blocks -- #read ) + block-size " dev-read-blocks" $call-parent + not IF + ." Read blocks failed !" cr -1 throw + THEN +; + +INSTANCE VARIABLE deblocker + +: open ( -- true | false ) + my-unit " set-address" $call-parent + is_cdrom IF " dev-prep-cdrom" ELSE " dev-prep-disk" THEN $call-parent + " dev-get-capacity" $call-parent to max-block-num to block-size + " dev-max-transfer" $call-parent to max-transfer + + 0 0 " deblocker" $open-package dup deblocker ! dup IF + " disk-label" find-package IF + my-args rot interpose + THEN + THEN 0<> +; + +: close ( -- ) + deblocker @ close-package ; + +: seek ( pos.lo pos.hi -- status ) + s" seek" deblocker @ $call-method ; + +: read ( addr len -- actual ) + s" read" deblocker @ $call-method ; + +finish-device diff --git a/board-qemu/slof/vio-vscsi.fs b/board-qemu/slof/vio-vscsi.fs new file mode 100644 index 0000000..7bf5ae8 --- /dev/null +++ b/board-qemu/slof/vio-vscsi.fs @@ -0,0 +1,623 @@ +\ ***************************************************************************** +\ * 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 + +0 CONSTANT vscsi-debug + +0 VALUE vscsi-unit + +\ ----------------------------------------------------------- +\ Direct DMA conversion hack +\ ----------------------------------------------------------- +: l2dma ( laddr - dma_addr) +; + +\ ----------------------------------------------------------- +\ CRQ related functions +\ ----------------------------------------------------------- + +0 VALUE crq-base +0 VALUE crq-dma +0 VALUE crq-offset +1000 CONSTANT CRQ-SIZE + +CREATE crq 10 allot + +: crq-alloc ( -- ) + \ XXX We rely on SLOF alloc-mem being aligned + CRQ-SIZE alloc-mem to crq-base 0 to crq-offset + crq-base l2dma to crq-dma +; + +: crq-free ( -- ) + vscsi-unit hv-free-crq + crq-base CRQ-SIZE free-mem 0 to crq-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 + +\ Storage for up to 256 bytes SRP request */ +CREATE srp 100 allot +0 VALUE srp-len + +: srp-prep-cmd-nodata ( id lun -- ) + srp /srp-cmd erase + SRP_CMD srp >srp-cmd-opcode c! + 1 srp >srp-cmd-tag x! + srp >srp-cmd-lun 1 + c! \ lun + srp >srp-cmd-lun c! \ id + /srp-cmd to srp-len +; + +: srp-prep-cmd-io ( addr len id lun -- ) + 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 id lun -- ) + 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 id lun -- ) + 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 ) + \ XXX FIXME: Always in same position + srp >srp-rsp-data +; + +: srp-wait-rsp ( -- true | [ ascq asc sense-key false ] ) + srp-wait-crq not IF false EXIT THEN + dup 1 <> IF + ." VSCSI: Invalid CRQ response tag, want 1 got " . cr + false EXIT + THEN drop + + srp >srp-rsp-tag x@ dup 1 <> IF + ." VSCSI: Invalid SRP response tag, want 1 got " . cr + false EXIT + THEN drop + + srp >srp-rsp-status c@ + vscsi-debug IF + ." VSCSI: Got response status: " + dup .status-text cr + THEN + + 0 <> IF + srp-rsp-find-sense + scsi-get-sense-data + vscsi-debug IF + ." VSCSI: Sense key: " dup .sense-text cr + THEN + false EXIT + THEN + true +; + + +\ ----------------------------------------------------------- +\ Core VSCSI +\ ----------------------------------------------------------- + +CREATE sector d# 512 allot + +0 VALUE current-id +0 VALUE current-lun + +\ SCSI test-unit-read +: test-unit-ready ( -- true | [ ascq asc sense-key false ] ) + current-id current-lun srp-prep-cmd-nodata + srp >srp-cmd-cdb scsi-build-test-unit-ready + srp-send-cmd + srp-wait-rsp +; + +: inquiry ( -- true | false ) + \ WARNING: ATAPI devices with libata seem to ignore the MSB of + \ the allocation length... let's only ask for ff bytes + sector ff current-id current-lun srp-prep-cmd-read + ff srp >srp-cmd-cdb scsi-build-inquiry + srp-send-cmd + srp-wait-rsp + dup not IF nip nip nip EXIT THEN \ swallow sense +; + +: read-capacity ( -- true | false ) + sector scsi-length-read-cap-10 current-id current-lun srp-prep-cmd-read + srp >srp-cmd-cdb scsi-build-read-cap-10 + srp-send-cmd + srp-wait-rsp + dup not IF nip nip nip EXIT THEN \ swallow sense +; + +: start-stop-unit ( state# -- true | false ) + current-id current-lun srp-prep-cmd-nodata + srp >srp-cmd-cdb scsi-build-start-stop-unit + srp-send-cmd + srp-wait-rsp + dup not IF nip nip nip EXIT THEN \ swallow sense +; + +: get-media-event ( -- true | false ) + sector scsi-length-media-event current-id current-lun srp-prep-cmd-read + srp >srp-cmd-cdb scsi-build-get-media-event + srp-send-cmd + srp-wait-rsp + dup not IF nip nip nip EXIT THEN \ swallow sense +; + +: read-blocks ( -- addr block# #blocks blksz -- [ #read-blocks true ] | false ) + over * ( addr block# #blocks len ) + >r rot r> ( block# #blocks addr len ) + 5 0 DO + 2dup current-id current-lun + srp-prep-cmd-read ( block# #blocks addr len ) + 2swap ( addr len block# #blocks ) + 2dup srp >srp-cmd-cdb scsi-build-read-10 ( addr len block# #blocks ) + 2swap ( block# #blocks addr len ) + srp-send-cmd + srp-wait-rsp + IF 2drop nip true UNLOOP EXIT THEN + srp >srp-rsp-status c@ 8 <> IF + nip nip nip 2drop 2drop false EXIT + THEN + 3drop + 100 ms + LOOP + 2drop 2drop false +; + +\ Cleanup behind us +: vscsi-cleanup + ." VSCSI: Cleaning up" cr + + crq-cleanup + + \ Disable TCE bypass + vscsi-unit 0 rtas-set-tce-bypass +; + +\ Initialize our vscsi instance +: vscsi-init ( -- true | false ) + ." VSCSI: Initializing" cr + + \ Can't use my-unit bcs we aren't instanciating (fix this ?) + " reg" get-node get-package-property IF + ." VSCSI: Not reg property !!!" 0 + THEN + decode-int to vscsi-unit 2drop + + \ 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 + ['] vscsi-cleanup add-quiesce-xt + + true +; + +\ ----------------------------------------------------------- +\ SCSI scan at boot and child device support +\ ----------------------------------------------------------- + +0 INSTANCE VALUE target-id +0 INSTANCE VALUE target-lun + +: set-address ( lun id -- ) + to target-id to target-lun +; + +: dev-max-transfer ( -- n ) + 10000 \ Larger value seem to have problems with some CDROMs +; + +: dev-get-capacity ( -- blocksize #blocks ) + target-id to current-id target-lun to current-lun + read-capacity not IF 0 0 EXIT THEN + sector scsi-get-capacity-10 +; + +: dev-read-blocks ( -- addr block# #blocks blksize -- #read-blocks ) + target-id to current-id target-lun to current-lun + read-blocks +; + +: initial-test-unit-ready ( -- true | [ ascq asc sense-key false ] ) + 0 0 0 false + 3 0 DO + 2drop 2drop + test-unit-ready dup IF UNLOOP EXIT THEN + LOOP +; + +: compare-sense ( ascq asc key ascq2 asc2 key2 -- true | false ) + 3 pick = ( ascq asc key ascq2 asc2 keycmp ) + swap 4 pick = ( ascq asc key ascq2 keycmp asccmp ) + rot 5 pick = ( ascq asc key keycmp asccmp ascqcmp ) + and and nip nip nip +; + +0 CONSTANT CDROM-READY +1 CONSTANT CDROM-NOT-READY +2 CONSTANT CDROM-NO-DISK +3 CONSTANT CDROM-TRAY-OPEN +4 CONSTANT CDROM-INIT-REQUIRED +5 CONSTANT CDROM-TRAY-MAYBE-OPEN + +: cdrom-status ( -- status ) + initial-test-unit-ready + IF CDROM-READY EXIT THEN + + vscsi-debug IF + ." TestUnitReady sense: " 3dup . . . cr + THEN + + 3dup 1 4 2 compare-sense IF + 3drop CDROM-NOT-READY EXIT + THEN + + get-media-event IF + sector w@ 4 >= IF + sector 2 + c@ 04 = IF + sector 5 + c@ + dup 02 and 0<> IF drop 3drop CDROM-READY EXIT THEN + dup 01 and 0<> IF drop 3drop CDROM-TRAY-OPEN EXIT THEN + drop 3drop CDROM-NO-DISK EXIT + THEN + THEN + THEN + + 3dup 2 4 2 compare-sense IF + 3drop CDROM-INIT-REQUIRED EXIT + THEN + over 4 = over 2 = and IF + \ Format in progress... what do we do ? Just ignore + 3drop CDROM-READY EXIT + THEN + over 3a = IF + 3drop CDROM-NO-DISK EXIT + THEN + + \ Other error... + 3drop CDROM-TRAY-MAYBE-OPEN +; + +: cdrom-try-close-tray ( -- ) + scsi-const-load start-stop-unit drop +; + +: cdrom-must-close-tray ( -- ) + scsi-const-load start-stop-unit not IF + ." Tray open !" cr -65 throw + THEN +; + +: dev-prep-cdrom ( -- ) + target-id to current-id target-lun to current-lun + + 5 0 DO + cdrom-status CASE + CDROM-READY OF UNLOOP EXIT ENDOF + CDROM-NO-DISK OF ." No medium !" cr -65 THROW ENDOF + CDROM-TRAY-OPEN OF cdrom-must-close-tray ENDOF + CDROM-INIT-REQUIRED OF cdrom-try-close-tray ENDOF + CDROM-TRAY-MAYBE-OPEN OF cdrom-try-close-tray ENDOF + ENDCASE + d# 1000 ms + LOOP + ." Drive not ready !" cr -65 THROW +; + +: dev-prep-disk ( -- ) +; + +: vscsi-create-disk ( lun id -- ) + " disk" 0 " vio-vscsi-device.fs" included +; + +: vscsi-create-cdrom ( lun id -- ) + " cdrom" 1 " vio-vscsi-device.fs" included +; + +: wrapped-inquiry ( -- true | false ) + inquiry not IF false EXIT THEN + \ Skip devices with PQ != 0 + sector inquiry-data>peripheral c@ e0 and 0 = +; + +8 CONSTANT #dev +: vscsi-find-disks ( -- ) + ." VSCSI: Looking for disks" cr + #dev 0 DO \ check 8 devices (no LUNs) + i to current-id 0 to current-lun + wrapped-inquiry IF + ." SCSI ID " i . + \ XXX FIXME: Check top bits to ignore unsupported units + \ and maybe provide better printout & more cases + sector inquiry-data>peripheral c@ CASE + 0 OF ." DISK : " 0 i vscsi-create-disk ENDOF + 5 OF ." CD-ROM : " 0 i vscsi-create-cdrom ENDOF + 7 OF ." OPTICAL : " 0 i vscsi-create-cdrom ENDOF + e OF ." RED-BLOCK: " 0 i vscsi-create-disk ENDOF + dup dup OF ." ? (" . 8 emit 29 emit 5 spaces ENDOF + ENDCASE + sector .inquiry-text cr + THEN + LOOP +; + +\ Remove scsi functions from word list +scsi-close + +: setup-alias + " scsi" find-alias 0= IF + " scsi" get-node node>path set-alias + ELSE THEN +; + +: vscsi-init-and-scan ( -- ) + vscsi-init IF + vscsi-find-disks + setup-alias + THEN +; + +vscsi-init-and-scan diff --git a/board-qemu/veth/Makefile b/board-qemu/veth/Makefile new file mode 100644 index 0000000..0032b8e --- /dev/null +++ b/board-qemu/veth/Makefile @@ -0,0 +1,50 @@ +# ***************************************************************************** +# * 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 TOP + TOP = $(shell while ! test -e make.rules; do cd .. ; done; pwd) + export TOP +endif +include $(TOP)/make.rules + +CFLAGS = -O2 -I./ -I$(TOP)/clients/net-snk/include/ -I$(TOP)/lib/libc/include/ +CFLAGS += -I$(TOP)/lib/libhvcall +CFLAGS += -fno-builtin -ffreestanding -fno-stack-protector -msoft-float -nostdinc -Wall + +SRCS = module_entry.c veth.c + +OBJS = $(SRCS:.c=.o) $(TOP)/lib/libhvcall/hvcall.o + +all: Makefile.dep net_veth.bin + +net_veth.o: $(OBJS) + $(LD) $(LDFLAGS) $^ -o $@ -T veth.lds -N + +net_veth.bin: net_veth.o + $(OBJCOPY) -O binary $^ $@ +clean: + $(RM) -f *.o *.a *.i *.bin + +distclean : clean + rm -f Makefile.dep + + +# Rules for creating the dependency file: +depend: + $(CC) -MM $(CFLAGS) $(SRCS) > Makefile.dep +Makefile.dep: + $(MAKE) depend + +# Include dependency file if available: +ifneq (,$(wildcard Makefile.dep)) +include Makefile.dep +endif diff --git a/board-qemu/veth/module_entry.c b/board-qemu/veth/module_entry.c new file mode 100644 index 0000000..30a3508 --- /dev/null +++ b/board-qemu/veth/module_entry.c @@ -0,0 +1,44 @@ +/****************************************************************************** + * 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 "netdriver_int.h" + +static void* memset( void *dest, int c, size_t n ) +{ + while( n-- ) { + *( char * ) dest++ = ( char ) c; + } + return dest; +} + +extern char __bss_start; +extern char __bss_size; + +extern snk_module_t* veth_module_init(snk_kernel_t *snk_kernel_int, + vio_config_t *conf); + +snk_module_t* module_init(snk_kernel_t *snk_kernel_int, pci_config_t *pciconf) +{ + char *bss = &__bss_start; + unsigned long long bss_size = (unsigned long long) &__bss_size; + vio_config_t *vioconf = (vio_config_t *)pciconf; + + if (((unsigned long long) bss) + bss_size >= 0xFF00000 + || bss_size >= 0x2000000) { + snk_kernel_int->print("BSS size (%llu bytes) is too big!\n", + bss_size); + return 0; + } + memset(bss, 0, bss_size); + + return veth_module_init(snk_kernel_int, vioconf); +} diff --git a/board-qemu/veth/veth.c b/board-qemu/veth/veth.c new file mode 100644 index 0000000..0bbaebe --- /dev/null +++ b/board-qemu/veth/veth.c @@ -0,0 +1,280 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +#include "types.h" +#include "netdriver_int.h" +#include "libhvcall.h" + +static snk_kernel_t *snk_kernel_interface; +static snk_module_t *snk_module_interface; +static unsigned int g_reg; + +#define printk(fmt...) do { snk_kernel_interface->print(fmt); } while(0) +#define malloc(args...) snk_kernel_interface->k_malloc(args) +#define malloc_aligned(args...) snk_kernel_interface->k_malloc_aligned(args) +#define free(args...) do { snk_kernel_interface->k_free(args); } while(0) + +#define dprintk(fmt...) +//#define dprintk(fmt...) printk(fmt) + +/* *** WARNING: We pass our addresses as-is as DMA addresses, + * we -do- rely on the forth code to have enabled TCE bypass + * on our device ! + */ +#define vaddr_to_dma(vaddr) ((u64)vaddr) + +struct ibmveth_buf_desc_fields { + u32 flags_len; +#define IBMVETH_BUF_VALID 0x80000000 +#define IBMVETH_BUF_TOGGLE 0x40000000 +#define IBMVETH_BUF_NO_CSUM 0x02000000 +#define IBMVETH_BUF_CSUM_GOOD 0x01000000 +#define IBMVETH_BUF_LEN_MASK 0x00FFFFFF + u32 address; +}; + +union ibmveth_buf_desc { + u64 desc; + struct ibmveth_buf_desc_fields fields; +}; + +struct ibmveth_rx_q_entry { + u32 flags_off; +#define IBMVETH_RXQ_TOGGLE 0x80000000 +#define IBMVETH_RXQ_TOGGLE_SHIFT 31 +#define IBMVETH_RXQ_VALID 0x40000000 +#define IBMVETH_RXQ_NO_CSUM 0x02000000 +#define IBMVETH_RXQ_CSUM_GOOD 0x01000000 +#define IBMVETH_RXQ_OFF_MASK 0x0000FFFF + + u32 length; + u64 correlator; +}; + +static void *buffer_list; +static void *filter_list; +static u64 *rx_bufs; +static u64 *rx_bufs_aligned; +static u32 cur_rx_toggle; +static u32 cur_rx_index; + +#define RX_QUEUE_SIZE 16 +#define RX_BUF_SIZE 2048 +#define RX_BUF_MULT (RX_BUF_SIZE >> 3) + +static struct ibmveth_rx_q_entry *rx_queue; + +static char * memcpy( char *dest, const char *src, size_t n ) +{ + char *ret = dest; + while( n-- ) { + *dest++ = *src++; + } + + return( ret ); +} + +static inline u64 *veth_get_rx_buf(unsigned int i) +{ + return &rx_bufs_aligned[i * RX_BUF_MULT]; +} + +static int veth_init(void) +{ + char *mac_addr = snk_module_interface->mac_addr; + union ibmveth_buf_desc rxq_desc; + unsigned long rx_queue_len = sizeof(struct ibmveth_rx_q_entry) * + RX_QUEUE_SIZE; + unsigned int i; + long rc; + + dprintk("veth_init(%02x:%02x:%02x:%02x:%02x:%02x)\n", + mac_addr[0], mac_addr[1], mac_addr[2], + mac_addr[3], mac_addr[4], mac_addr[5]); + + if (snk_module_interface->running != 0) + return 0; + + cur_rx_toggle = IBMVETH_RXQ_TOGGLE; + cur_rx_index = 0; + buffer_list = malloc_aligned(8192, 4096); + filter_list = buffer_list + 4096; + rx_queue = malloc_aligned(rx_queue_len, 16); + rx_bufs = malloc(2048 * RX_QUEUE_SIZE + 4); + if (!buffer_list || !filter_list || !rx_queue || !rx_bufs) { + printk("veth: Failed to allocate memory !\n"); + goto fail; + } + rx_bufs_aligned = (u64 *)(((u64)rx_bufs | 3) + 1); + rxq_desc.fields.address = vaddr_to_dma(rx_queue); + rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | rx_queue_len; + + rc = h_register_logical_lan(g_reg, + vaddr_to_dma(buffer_list), + rxq_desc.desc, + vaddr_to_dma(filter_list), + (*(u64 *)mac_addr) >> 16); + if (rc != H_SUCCESS) { + printk("veth: Error %ld registering interface !\n", rc); + goto fail; + } + for (i = 0; i < RX_QUEUE_SIZE; i++) { + u64 *buf = veth_get_rx_buf(i); + union ibmveth_buf_desc desc; + *buf = (u64)buf; + desc.fields.address = vaddr_to_dma(buf); + desc.fields.flags_len = IBMVETH_BUF_VALID | RX_BUF_SIZE; + h_add_logical_lan_buffer(g_reg, desc.desc); + } + + snk_module_interface->running = 1; + + return 0; + fail: + if (filter_list) + free(filter_list); + if (buffer_list) + free(buffer_list); + if (rx_queue) + free(rx_queue); + if (rx_bufs) + free(rx_bufs); + return -1; +} + +static int veth_term(void) +{ + dprintk("veth_term()\n"); + + if (snk_module_interface->running == 0) + return 0; + + h_free_logical_lan(g_reg); + + if (filter_list) + free(filter_list); + if (buffer_list) + free(buffer_list); + if (rx_queue) + free(rx_queue); + if (rx_bufs) + free(rx_bufs); + + snk_module_interface->running = 0; + + return 0; +} + +static int veth_xmit(char *f_buffer_pc, int f_len_i) +{ + union ibmveth_buf_desc tx_desc; + long rc; + + dprintk("veth_xmit(packet at %p, %d bytes)\n", f_buffer_pc, f_len_i); + + tx_desc.fields.address = vaddr_to_dma(f_buffer_pc); + tx_desc.fields.flags_len = IBMVETH_BUF_VALID | f_len_i; + + rc = hv_send_logical_lan(g_reg, tx_desc.desc, 0, 0, 0, 0, 0); + if (rc != H_SUCCESS) { + printk("veth: Error %ld sending packet !\n", rc); + return -1; + } + + return f_len_i; +} + +static int veth_receive(char *f_buffer_pc, int f_len_i) +{ + int packet = 0; + + dprintk("veth_receive()\n"); + + while(!packet) { + struct ibmveth_rx_q_entry *desc = &rx_queue[cur_rx_index]; + union ibmveth_buf_desc bdesc; + void *buf; + + if ((desc->flags_off & IBMVETH_RXQ_TOGGLE) != cur_rx_toggle) + break; + + if (!(desc->flags_off & IBMVETH_RXQ_VALID)) + goto recycle; + if (desc->length > f_len_i) { + printk("veth: Dropping too big packet [%d bytes]\n", + desc->length); + goto recycle; + } + + buf = (void *)desc->correlator; + packet = desc->length; + memcpy(f_buffer_pc, + buf + (desc->flags_off & IBMVETH_RXQ_OFF_MASK), packet); + recycle: + bdesc.fields.address = vaddr_to_dma(buf); + bdesc.fields.flags_len = IBMVETH_BUF_VALID | RX_BUF_SIZE; + h_add_logical_lan_buffer(g_reg, bdesc.desc); + + cur_rx_index = (cur_rx_index + 1) % RX_QUEUE_SIZE; + if (cur_rx_index == 0) + cur_rx_toggle ^= IBMVETH_RXQ_TOGGLE; + } + + return packet; +} + +static int veth_ioctl(int request, void* data) +{ + dprintk("veth_ioctl()\n"); + + return 0; +} + +static snk_module_t veth_interface = { + .version = 1, + .type = MOD_TYPE_NETWORK, + .running = 0, + .init = veth_init, + .term = veth_term, + .write = veth_xmit, + .read = veth_receive, + .ioctl = veth_ioctl +}; + + +static int check_driver(vio_config_t *conf) +{ + + if (snk_kernel_interface->strcmp(conf->compat, "IBM,l-lan")) { + printk( "veth: netdevice not supported\n" ); + return -1; + } + g_reg = conf->reg; + + return 0; +} + +snk_module_t* veth_module_init(snk_kernel_t *snk_kernel_int, vio_config_t *conf) +{ + snk_kernel_interface = snk_kernel_int; + snk_module_interface = &veth_interface; + + if (snk_kernel_int->version != snk_module_interface->version) + return 0; + + /* Check if this is the right driver */ + if (check_driver(conf) < 0) + return 0; + + snk_module_interface->link_addr = module_init; + return snk_module_interface; +} diff --git a/board-qemu/veth/veth.lds b/board-qemu/veth/veth.lds new file mode 100644 index 0000000..a0c75d5 --- /dev/null +++ b/board-qemu/veth/veth.lds @@ -0,0 +1,39 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +OUTPUT_FORMAT("elf64-powerpc", "elf64-powerpc", "elf64-powerpc") +OUTPUT_ARCH(powerpc:common64) +ENTRY(module_init) + +SECTIONS { + .code 0xF800000: + { + module_entry.o(.opd) + *(.text .stub .text.* .gnu.linkonce.t.*) + *(.sfpr .glink) + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.data .data.* .gnu.linkonce.d.*) + *(.opd) + } + .got : + { + _got = .; + *(.got .toc) + } + .bss : { + __bss_start = .; + *(*COM* .bss .gnu.linkonce.b.*) + __bss_end = .; + } + __bss_size = (__bss_end - __bss_start); + __end = .; +} diff --git a/clients/net-snk/include/netdriver_int.h b/clients/net-snk/include/netdriver_int.h index 375f2c5..2f286ad 100644 --- a/clients/net-snk/include/netdriver_int.h +++ b/clients/net-snk/include/netdriver_int.h @@ -28,6 +28,7 @@ typedef struct { int type; } bar_t; + typedef struct { unsigned long long puid; unsigned int bus; @@ -40,6 +41,11 @@ typedef struct { unsigned int interrupt_line; } pci_config_t; +typedef struct { + unsigned int reg; + char compat[64]; +} vio_config_t; + #define MOD_TYPE_NETWORK 0 #define MOD_TYPE_OTHER 1 @@ -112,7 +118,10 @@ typedef struct { io_write_t io_write; romfs_lookup_t k_romfs_lookup; translate_addr_t translate_addr; - pci_config_t pci_conf; + union { + pci_config_t pci_conf; + vio_config_t vio_conf; + }; k_open_t k_open; k_close_t k_close; k_read_t k_read; diff --git a/clients/net-snk/kernel/modules.c b/clients/net-snk/kernel/modules.c index 9d4281c..91ed959 100644 --- a/clients/net-snk/kernel/modules.c +++ b/clients/net-snk/kernel/modules.c @@ -38,6 +38,7 @@ static const mod_descriptor_t modules[] = { { "net_nx203x", (void*) 0xF800000, MOD_TYPE_NETWORK }, { "net_mcmal" , (void*) 0xF800000, MOD_TYPE_NETWORK }, { "net_spider", (void*) 0xF800000, MOD_TYPE_NETWORK }, + { "net_veth", (void*) 0xF800000, MOD_TYPE_NETWORK }, { "mod_paflof", (void*) 0x6200000, MOD_TYPE_OTHER }, { 0 , (void*) 0 } }; diff --git a/clients/net-snk/libc/Makefile b/clients/net-snk/libc/Makefile index aed7d9b..74c9ead 100644 --- a/clients/net-snk/libc/Makefile +++ b/clients/net-snk/libc/Makefile @@ -19,7 +19,9 @@ include $(TOP)/make.rules CFLAGS = -g -I$(TOP)/include -I$(LIBCMNDIR)/libc/include -O2 \ - -fno-builtin -ffreestanding -nostdinc -msoft-float -Wall + -fno-builtin -ffreestanding -nostdinc -msoft-float -Wall \ + -fno-stack-protector + LDFLAGS= -nostdlib OBJS = sbrk.o io.o ioctl.o diff --git a/clients/net-snk/libc/socket/Makefile b/clients/net-snk/libc/socket/Makefile index d4bd4be..a1c5039 100644 --- a/clients/net-snk/libc/socket/Makefile +++ b/clients/net-snk/libc/socket/Makefile @@ -19,7 +19,8 @@ include $(TOP)/make.rules CFLAGS = -g -I$(TOP)/include -I$(LIBCMNDIR)/libc/include -O2 \ - -fno-builtin -ffreestanding -msoft-float -Wall + -fno-builtin -ffreestanding -msoft-float -Wall \ + -fno-stack-protector LDFLAGS= -nostdlib diff --git a/clients/net-snk/libc/time/Makefile b/clients/net-snk/libc/time/Makefile index fa90b01..46b7d4e 100644 --- a/clients/net-snk/libc/time/Makefile +++ b/clients/net-snk/libc/time/Makefile @@ -20,7 +20,7 @@ include $(TOP)/make.rules CFLAGS = -g -I$(TOP)/include -I$(LIBCMNDIR)/libc/include -O2 -msoft-float \ - -Wall -fno-builtin -ffreestanding -nostdinc + -Wall -fno-builtin -ffreestanding -nostdinc -fno-stack-protector LDFLAGS= -nostdlib diff --git a/clients/net-snk/make.rules b/clients/net-snk/make.rules index 060e659..be492d7 100644 --- a/clients/net-snk/make.rules +++ b/clients/net-snk/make.rules @@ -21,7 +21,7 @@ LIBCMNDIR ?= $(ROOTDIR)/lib CFLAGS = -g -I. -I$(TOP)/include -I$(LIBCMNDIR)/libc/include \ -I$(LIBCMNDIR)/libbootmsg -I$(INCLCMNDIR)/$(CPUARCH) \ -O2 -fno-builtin -ffreestanding -msoft-float -mno-altivec \ - -Wall $(FLAG) -nostdinc + -Wall $(FLAG) -nostdinc -fno-stack-protector ifeq ($(SNK_LJTAG_PROCESS), 1) CFLAGS += -I$(TOP)/../../board-malta/include CFLAGS += -I$(TOP)/../../include/cbea diff --git a/clients/net-snk/oflib/of.c b/clients/net-snk/oflib/of.c index 5b8256d..a4d98b8 100644 --- a/clients/net-snk/oflib/of.c +++ b/clients/net-snk/oflib/of.c @@ -691,17 +691,21 @@ get_puid(phandle_t node) return 0; } +static int set_vio_config(vio_config_t * vio_config, phandle_t net) +{ + of_getprop(net, "reg", &vio_config->reg, 4); + of_getprop(net, "compatible", &vio_config->compat, 64); + + return 0; +} + /* Fill in the pci config structure from the device tree */ -static int -set_pci_config(pci_config_t * pci_config) +static int set_pci_config(pci_config_t * pci_config, phandle_t net) { - unsigned char buf[1024]; + unsigned char buf[400]; int len, bar_nr; unsigned int *assigned_ptr; - phandle_t net = get_boot_device(); - if (net == -1) - return -1; of_getprop(net, "vendor-id", &pci_config->vendor_id, 4); of_getprop(net, "device-id", &pci_config->device_id, 4); of_getprop(net, "revision-id", &pci_config->revision_id, 4); @@ -732,6 +736,21 @@ set_pci_config(pci_config_t * pci_config) return 0; } +static int set_config(snk_kernel_t * snk_kernel_interface) +{ + phandle_t parent, net = get_boot_device(); + char compat[64]; + + if (net == -1) + return -1; + + parent = of_parent(net); + of_getprop(parent, "compatible", compat, 64); + if (!strcmp(compat, "IBM,vdevice")) + return set_vio_config(&snk_kernel_interface->vio_conf, net); + return set_pci_config(&snk_kernel_interface->pci_conf, net); +} + void get_mac(char *mac) { @@ -792,7 +811,7 @@ glue_init(snk_kernel_t * snk_kernel_interface, unsigned int * timebase, return -2; /* Setup Kernel Struct */ - if (set_pci_config(&snk_kernel_interface->pci_conf) == -1) { + if (set_config(snk_kernel_interface) == -1) { snk_kernel_interface->print(" No net device found \n"); } diff --git a/clients/net-snk/oflib/pci.c b/clients/net-snk/oflib/pci.c index dac629a..2a75829 100644 --- a/clients/net-snk/oflib/pci.c +++ b/clients/net-snk/oflib/pci.c @@ -16,6 +16,7 @@ #include <string.h> #include <kernel.h> #include <cpu.h> +#include <cache.h> int pci_calc_bar_size(long long puid, int bus, int devfn, int bar) @@ -49,19 +50,13 @@ read_io(void *addr, size_t sz) switch (sz) { case 1: - set_ci(); - ret = (unsigned int) *((unsigned char *) addr); - clr_ci(); + ret = ci_read_8(addr); break; case 2: - set_ci(); - ret = (unsigned int) *((unsigned short *) addr); - clr_ci(); + ret = ci_read_16(addr); break; case 4: - set_ci(); - ret = *((unsigned int *) addr); - clr_ci(); + ret = ci_read_32(addr); break; default: ret = 0; @@ -75,19 +70,13 @@ write_io(void *addr, unsigned int value, size_t sz) { switch (sz) { case 1: - set_ci(); - *((unsigned char *) addr) = (unsigned char) value; - clr_ci(); + ci_write_8(addr, value); break; case 2: - set_ci(); - *((unsigned short *) addr) = (unsigned short) value; - clr_ci(); + ci_write_16(addr, value); break; case 4: - set_ci(); - *((unsigned int *) addr) = value; - clr_ci(); + ci_write_32(addr, value); break; default: return -1; diff --git a/include/ppcp7/cache.h b/include/ppcp7/cache.h new file mode 100644 index 0000000..ecbec1c --- /dev/null +++ b/include/ppcp7/cache.h @@ -0,0 +1,62 @@ +/****************************************************************************** + * 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 __CACHE_H +#define __CACHE_H + +#include <cpu.h> +#include <stdint.h> + +// XXX FIXME: Use proper CI load/store */ +#define cache_inhibited_access(type,name) \ + static inline type ci_read_##name(type * addr) \ + { \ + type val; \ + val = *addr; \ + return val; \ + } \ + static inline void ci_write_##name(type * addr, type data) \ + { \ + *addr = data; \ + } + +cache_inhibited_access(uint8_t, 8) +cache_inhibited_access(uint16_t, 16) +cache_inhibited_access(uint32_t, 32) +cache_inhibited_access(uint64_t, 64) + +static inline uint16_t bswap16_load(uint64_t addr) +{ + unsigned int val; + asm volatile ("lhbrx %0, 0, %1":"=r" (val):"r"(addr)); + return val; +} + +static inline uint32_t bswap32_load(uint64_t addr) +{ + unsigned int val; + asm volatile ("lwbrx %0, 0, %1":"=r" (val):"r"(addr)); + return val; +} + +static inline void bswap16_store(uint64_t addr, uint16_t val) +{ + asm volatile ("sthbrx %0, 0, %1"::"r" (val), "r"(addr)); +} + +static inline void bswap32_store(uint64_t addr, uint32_t val) +{ + asm volatile ("stwbrx %0, 0, %1"::"r" (val), "r"(addr)); +} + +#endif /* __CACHE_H */ + diff --git a/include/ppcp7/cpu.h b/include/ppcp7/cpu.h new file mode 100644 index 0000000..6de50d7 --- /dev/null +++ b/include/ppcp7/cpu.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * 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 __CPU_H +#define __CPU_H + +/* Used in boot_abort.S, will need something better for KVM */ +#define HSPRG0 304 + +/* XXX FIXME: Can be more efficient, no dcbst nor loop needed on P7 */ +/* This macro uses r0 */ +#define FLUSH_CACHE(r, n) add n, n, r; \ + addi n, n, 127; \ + rlwinm r, r, 0,0,24; \ + rlwinm n, n, 0,0,24; \ + sub n, n, r; \ + srwi n, n, 7; \ + mtctr n; \ + 0: dcbst 0, r; \ + sync; \ + icbi 0, r; \ + sync; \ + isync; \ + addi r, r, 128; \ + bdnz 0b; + +#ifndef __ASSEMBLER__ +#define STRINGIFY(x...) #x +#define EXPAND(x) STRINGIFY(x) + +static inline void flush_cache(void* r, long n) +{ + asm volatile(EXPAND(FLUSH_CACHE(%0, %1)) + : "+r"(r), "+r"(n) + :: "memory", "cc", "r0", "ctr"); +} + + +#endif /* __ASSEMBLER__ */ + +#endif diff --git a/lib/Makefile b/lib/Makefile index 34d3c23..ae03f8f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -10,7 +10,7 @@ # * IBM Corporation - initial implementation # ****************************************************************************/ -SUBDIRS = libc libipmi libbootmsg libbases libnvram libelf +SUBDIRS = libc libipmi libbootmsg libbases libnvram libelf libhvcall all: subdirs diff --git a/lib/libbootmsg/Makefile b/lib/libbootmsg/Makefile index 6804b8d..891987e 100644 --- a/lib/libbootmsg/Makefile +++ b/lib/libbootmsg/Makefile @@ -33,12 +33,16 @@ ifeq ($(CPUARCH),p5) SRCS = SRCSS = bootmsg_lvl.S else +ifeq ($(CPUARCH),ppcp7) +SRCS = +SRCSS = bootmsg_lvl.S +else SRCS = bootmsg.c SRCSS = endif endif endif - +endif OBJS = $(SRCS:%.c=%.o) $(SRCSS:%.S=%.o) diff --git a/lib/libbootmsg/bootmsg_lvl.S b/lib/libbootmsg/bootmsg_lvl.S index 04ace12..65cf0c3 100644 --- a/lib/libbootmsg/bootmsg_lvl.S +++ b/lib/libbootmsg/bootmsg_lvl.S @@ -158,13 +158,16 @@ ENTRY(bootmsg_setlevel) andi. r3, r3, 0x7F add r6,r3,r6 // address | stb r4,0(r6) // store level |_ stwbrx r4,r3,r6 +#ifndef DISABLE_NVRAM LOAD64(r6, SB_NVRAM_FWONLY_adr + 8 ) add r6,r6,r3 stb r4,0(r6) +#endif mtlr r5 blr ENTRY(bootmsg_nvupdate) +#ifndef DISABLE_NVRAM mflr r10 LOAD64(r3, SB_NVRAM_FWONLY_adr) lwz r4, 0(r3) @@ -196,4 +199,5 @@ ENTRY(bootmsg_nvupdate) 2: // the end mtlr r10 +#endif blr diff --git a/lib/libhvcall/Makefile b/lib/libhvcall/Makefile new file mode 100644 index 0000000..41ee633 --- /dev/null +++ b/lib/libhvcall/Makefile @@ -0,0 +1,53 @@ +# ***************************************************************************** +# * 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 +# ****************************************************************************/ + +TOPCMNDIR ?= ../.. + +ASFLAGS = $(FLAG) $(RELEASE) $(CPUARCHDEF) -Wa,-mregnames +CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLBRDDIR) -I. -I../../include +LDFLAGS = -nostdlib + +TARGET = ../libhvcall.a + + +all: $(TARGET) + +SRCSS = hvcall.S + + +OBJS = $(SRCS:%.c=%.o) $(SRCSS:%.S=%.o) + +$(TARGET): $(OBJS) + $(AR) -rc $@ $(OBJS) + $(RANLIB) $@ + +%.o: %.S + $(CC) $(CPPFLAGS) $(ASFLAGS) -c $< -o $@ + +clean: + $(RM) $(TARGET) $(OBJS) + +distclean: clean + $(RM) Makefile.dep + + +# Rules for creating the dependency file: +depend: + $(RM) Makefile.dep + $(MAKE) Makefile.dep + +Makefile.dep: Makefile + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $(SRCS) $(SRCSS) > Makefile.dep + +# Include dependency file if available: +-include Makefile.dep + diff --git a/lib/libhvcall/hvcall.S b/lib/libhvcall/hvcall.S new file mode 100644 index 0000000..5cc0bd7 --- /dev/null +++ b/lib/libhvcall/hvcall.S @@ -0,0 +1,86 @@ +#define _ASM +#define __ASSEMBLY__ +#include "macros.h" +#include "libhvcall.h" + +#define HVCALL .long 0x44000022 + + .text + .align 3 + +ENTRY(hv_generic) + HVCALL + blr + +ENTRY(hv_putchar) + sldi r6,r3,(24+32) + li r3,H_PUT_TERM_CHAR + li r4,0 + li r5,1 + HVCALL + blr + +ENTRY(hv_getchar) + mflr r10 + bl .hv_haschar + mtlr r10 + cmpwi cr0,r3,0 + beqlr + lis r9,inbuf@h + ori r9,r9,inbuf@l + lwz r4,20(r9) + lbzx r3,r4,r9 + addi r4,r4,1 + stw r4,20(r9) + blr + +ENTRY(hv_haschar) + li r3,-1 + lis r9,inbuf@h + ori r9,r9,inbuf@l + lwz r5,16(r9) + lwz r6,20(r9) + cmplw cr0,r5,r6 + bnelr + li r3,H_GET_TERM_CHAR + li r4,0 + HVCALL + lis r9,inbuf@h + ori r9,r9,inbuf@l + stw r4,16(r9) + li r3,0 + stw r3,20(r9) + cmplwi cr0,r4,0 + beqlr + li r3,-1 + std r5,0(r9) + std r6,8(r9) + blr + +ENTRY(hv_send_crq) + ld r5,0(r4) + ld r6,8(r4) + mr r4,r3 + li r3,H_SEND_CRQ + HVCALL + blr + +ENTRY(hv_send_logical_lan) + li r11,0 /* no continue token for now */ + mr r10,r9 + mr r9,r8 + mr r8,r7 + mr r7,r6 + mr r6,r5 + mr r5,r4 + mr r4,r3 + li r3,H_SEND_LOGICAL_LAN + HVCALL + blr + + .section ".bss" + inbuf: .space 16 +inlen: .space 4 +inpos: .space 4 + .text +
\ No newline at end of file diff --git a/lib/libhvcall/hvcall.code b/lib/libhvcall/hvcall.code new file mode 100644 index 0000000..4e47c06 --- /dev/null +++ b/lib/libhvcall/hvcall.code @@ -0,0 +1,51 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ +#include <libhvcall.h> + +// : hv-putchar ( char -- ) +PRIM(hv_X2d_putchar) + char c = TOS.n; POP; + hv_putchar(c); +MIRP + +// : hv-getchar ( -- char ) +PRIM(hv_X2d_getchar) + PUSH; + TOS.n = hv_getchar(); +MIRP + +// : hv-haschar ( -- res ) +PRIM(hv_X2d_haschar) + PUSH; + TOS.n = hv_haschar(); +MIRP + +// : hv-reg-crq ( unit qaddr qsize -- res ) +PRIM(hv_X2d_reg_X2d_crq) + unsigned long qsize = TOS.u; POP; + unsigned long qaddr = TOS.u; POP; + unsigned int unit = TOS.u; + TOS.n = hv_reg_crq(unit, qaddr, qsize); +MIRP + +// : hv-free-crq ( unit -- ) +PRIM(hv_X2d_free_X2d_crq) + unsigned int unit = TOS.u; POP; + hv_free_crq(unit); +MIRP + +// : hv-send-crq ( unit msgaddr -- rc ) +PRIM(hv_X2d_send_X2d_crq) + uint64_t *msgaddr = (uint64_t *)TOS.u; POP; + unsigned int unit = TOS.u; + TOS.n = hv_send_crq(unit, msgaddr); +MIRP diff --git a/lib/libhvcall/hvcall.in b/lib/libhvcall/hvcall.in new file mode 100644 index 0000000..827aed4 --- /dev/null +++ b/lib/libhvcall/hvcall.in @@ -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 + *****************************************************************************/ + +cod(hv-putchar) +cod(hv-getchar) +cod(hv-haschar) +cod(hv-reg-crq) +cod(hv-free-crq) +cod(hv-send-crq) diff --git a/lib/libhvcall/libhvcall.h b/lib/libhvcall/libhvcall.h new file mode 100644 index 0000000..db1d890 --- /dev/null +++ b/lib/libhvcall/libhvcall.h @@ -0,0 +1,65 @@ +#ifndef __LIBHVCALL_H__ +#define __LIBHVCALL_H__ + +#define H_SUCCESS 0 + +#define H_GET_TERM_CHAR 0x54 +#define H_PUT_TERM_CHAR 0x58 +#define H_REG_CRQ 0xFC +#define H_FREE_CRQ 0x100 +#define H_SEND_CRQ 0x108 +#define H_REGISTER_LOGICAL_LAN 0x114 +#define H_FREE_LOGICAL_LAN 0x118 +#define H_ADD_LOGICAL_LAN_BUFFER 0x11C +#define H_SEND_LOGICAL_LAN 0x120 + +#ifndef __ASSEMBLY__ + +extern long hv_generic(unsigned long opcode, ...); + +extern void hv_putchar(char c); +extern char hv_getchar(void); +extern char hv_haschar(void); + +extern int hv_send_crq(unsigned int unit, uint64_t *msgaddr); + +static inline long hv_reg_crq(unsigned int unit, unsigned long qaddr, + unsigned long qsize) +{ + return hv_generic(H_REG_CRQ, unit, qaddr, qsize); +} + +static inline void hv_free_crq(unsigned int unit) +{ + hv_generic(H_FREE_CRQ, unit); +} + +extern long hv_send_logical_lan(unsigned long unit_address, + unsigned long desc1, unsigned long desc2, + unsigned long desc3, unsigned long desc4, + unsigned long desc5, unsigned long desc6); + +static inline long h_register_logical_lan(unsigned long unit_address, + unsigned long buf_list, + unsigned long rec_q, + unsigned long filter_list, + unsigned long mac_address) +{ + return hv_generic(H_REGISTER_LOGICAL_LAN, unit_address, + buf_list, rec_q, filter_list, mac_address); +} + +static inline long h_free_logical_lan(unsigned long unit_address) +{ + return hv_generic(H_FREE_LOGICAL_LAN, unit_address); +} + +static inline long h_add_logical_lan_buffer(unsigned long unit_address, + unsigned long buffer) +{ + return hv_generic(H_ADD_LOGICAL_LAN_BUFFER, unit_address, buffer); +} + +#endif /* __ASSEMBLY__ */ + +#endif /* __LIBHVCALL_H__ */ diff --git a/lib/libnvram/Makefile b/lib/libnvram/Makefile index 6c9ec84..afd536f 100644 --- a/lib/libnvram/Makefile +++ b/lib/libnvram/Makefile @@ -15,7 +15,8 @@ SRCS = nvram.c envvar.c TOPCMNDIR ?= ../.. ASFLAGS = $(FLAG) $(RELEASE) $(CPUARCHDEF) -Wa,-mregnames -CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLBRDDIR) -I$(INCLCMNDIR)/$(CPUARCH) -I. -I../../include +CPPFLAGS = -I../libc/include $(CPUARCHDEF) $(FLAG) \ + -I$(INCLBRDDIR) -I$(INCLCMNDIR)/$(CPUARCH) -I. -I../../include LDFLAGS = -nostdlib TARGET = ../libnvram.a diff --git a/lib/libnvram/nvram.c b/lib/libnvram/nvram.c index a31bb53..e9500ec 100644 --- a/lib/libnvram/nvram.c +++ b/lib/libnvram/nvram.c @@ -23,9 +23,17 @@ #include <southbridge.h> #include <nvramlog.h> +#ifndef NVRAM_LENGTH +#define NVRAM_LENGTH 0x10000 +#endif + void asm_cout(long Character,long UART,long NVRAM); -static volatile uint8_t *nvram=(volatile uint8_t *)SB_NVRAM_adr; +#if defined(DISABLE_NVRAM) +static volatile uint8_t nvram[NVRAM_LENGTH]; /* FAKE */ +#else +static volatile uint8_t *nvram = (volatile uint8_t *)SB_NVRAM_adr; +#endif /* This is extremely ugly, but still better than implementing * another sbrk() around it. @@ -490,13 +498,13 @@ void reset_nvram(void) erase_nvram(0, NVRAM_LENGTH); DEBUG("Creating CPU log partitions\n"); - *(uint32_t *)&(header[0]) = be32_to_cpu(LLFW_LOG_BE0_NAME_PREFIX); - *(uint64_t *)&(header[4]) = be64_to_cpu(LLFW_LOG_BE0_NAME); + *(uint32_t *)(char *)&(header[0]) = be32_to_cpu(LLFW_LOG_BE0_NAME_PREFIX); + *(uint64_t *)(char *)&(header[4]) = be64_to_cpu(LLFW_LOG_BE0_NAME); cpulog0=create_nvram_partition(LLFW_LOG_BE0_SIGNATURE, header, (LLFW_LOG_BE0_LENGTH*16)-PARTITION_HEADER_SIZE); - *(uint32_t *)&(header[0]) = be32_to_cpu(LLFW_LOG_BE1_NAME_PREFIX); - *(uint64_t *)&(header[4]) = be64_to_cpu(LLFW_LOG_BE1_NAME); + *(uint32_t *)(char *)&(header[0]) = be32_to_cpu(LLFW_LOG_BE1_NAME_PREFIX); + *(uint64_t *)(char *)&(header[4]) = be64_to_cpu(LLFW_LOG_BE1_NAME); cpulog1=create_nvram_partition(LLFW_LOG_BE1_SIGNATURE, header, (LLFW_LOG_BE1_LENGTH*16)-PARTITION_HEADER_SIZE); @@ -512,7 +520,8 @@ void reset_nvram(void) void nvram_debug(void) { +#if !defined(DISABLE_NVRAM) printf("\nNVRAM_BASE: %lx\n", (unsigned long)SB_NVRAM_adr); printf("NVRAM_LEN: %x\n", NVRAM_LENGTH); +#endif } - diff --git a/llfw/nvramlog.S b/llfw/nvramlog.S index c6e7418..be6bfd8 100644 --- a/llfw/nvramlog.S +++ b/llfw/nvramlog.S @@ -14,6 +14,9 @@ #include <southbridge.h> #include <calculatecrc.h> + +#if !defined(DISABLE_NVRAM) + // detect overflow: if(a<b) return a else return 0 #define NVRAM_LOG_DATA_OVERFLOW( a, b) \ cmpd 7, a, b; \ @@ -338,3 +341,11 @@ ASM_ENTRY(.calPartitionHeaderChecksum) mr r4, r6 blr + +#else /* defined(DISABLE_NVRAM) */ + +ASM_ENTRY(.writeNVRAMbyte) + ENTRY(writeLogByte) + blr + +#endif @@ -42,7 +42,7 @@ AR ?= $(CROSS)ar RANLIB ?= $(CROSS)ranlib CFLAGS ?= -g -O2 -fno-builtin -ffreestanding -nostdinc -msoft-float \ - -mno-altivec -mabi=no-altivec -Wall + -mno-altivec -mabi=no-altivec -Wall -fno-stack-protector export CC AS LD CLEAN OBJCOPY OBJDUMP STRIP AR RANLIB CFLAGS diff --git a/romfs/tools/create_crc.c b/romfs/tools/create_crc.c index 38235e5..8ea6347 100644 --- a/romfs/tools/create_crc.c +++ b/romfs/tools/create_crc.c @@ -124,7 +124,7 @@ createHeaderImage(int notime) memcpy(uHeader.stHeader.date, &da, 8); /* write Magic value into data stream */ - strcpy(uHeader.stHeader.magic, FLASHFS_MAGIC); + strncpy(uHeader.stHeader.magic, FLASHFS_MAGIC, 8); /* write platform name into data stream */ strcpy(uHeader.stHeader.platform_name, FLASHFS_PLATFORM_MAGIC); /* write platform revision into data stream */ diff --git a/slof/Makefile.inc b/slof/Makefile.inc index a8b3a37..cfc0451 100644 --- a/slof/Makefile.inc +++ b/slof/Makefile.inc @@ -28,7 +28,8 @@ INCLBRDDIR ?= $(TOPBRDDIR)/include CPPFLAGS += -I. -I$(INCLCMNDIR) -I$(INCLBRDDIR) -I$(INCLCMNDIR)/$(CPUARCH) CFLAGS = -DTARG=$(TARG) -static -Wall -W -std=gnu99 \ - -O2 -fomit-frame-pointer -msoft-float $(FLAG) $(CPUARCHDEF) + -O2 -fomit-frame-pointer -msoft-float $(FLAG) $(CPUARCHDEF) \ + -fno-stack-protector ASFLAGS = -Wa,-mpower4 -Wa,-mregnames $(FLAG) $(CPUARCHDEF) LDFLAGS += -static -nostdlib @@ -89,7 +90,7 @@ paflof: $(SLOFCMNDIR)/OF.lds $(SLOFCMNDIR)/ofw.o paflof.o $(SLOFCMNDIR)/entry.o @cp $@ $@.unstripped $(STRIP) -s $@ -paflof.o: +paflof.o: board.code dict.xt $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $(SLOFCMNDIR)/paflof.c $(SLOFCMNDIR)/xvect.bin: $(SLOFCMNDIR)/lowmem.o diff --git a/slof/fs/base.fs b/slof/fs/base.fs index 33fe7bc..8452f92 100644 --- a/slof/fs/base.fs +++ b/slof/fs/base.fs @@ -482,9 +482,9 @@ defer cursor-off ( -- ) : nop-reboot ( -- ) ." reboot not available" abort ; : nop-halt ( -- ) ." halt not available" abort ; -: nop-disable-watchdog ( -- ) ." disable-watchdog not available" cr ; -: nop-reset-watchdog ( -- ) ." reset-watchdog not available" cr ; -: nop-set-watchdog ( +n -- ) drop ." set-watchdog not available" cr ; +: nop-disable-watchdog ( -- ) ; +: nop-reset-watchdog ( -- ) ; +: nop-set-watchdog ( +n -- ) drop ; : nop-set-led ( type instance state -- status ) drop drop drop ; : nop-get-flashside ( -- side ) ." Cannot get flashside" cr ABORT ; : nop-set-flashside ( side -- status ) ." Cannot set flashside" cr ABORT ; diff --git a/slof/fs/envvar.fs b/slof/fs/envvar.fs index 8a2932d..cdf9226 100644 --- a/slof/fs/envvar.fs +++ b/slof/fs/envvar.fs @@ -264,6 +264,7 @@ VARIABLE nvoff \ offset in envvar partition : get-nv ( -- ) nvram-partition-type-common get-nvram-partition ( addr offset not-found | not-found ) \ find partition header IF + ." No NVRAM common partition, re-initializing..." cr internal-reset-nvram (nvupdate) nvram-partition-type-common get-nvram-partition IF ." NVRAM seems to be broken." cr EXIT THEN diff --git a/slof/fs/scsi-support.fs b/slof/fs/scsi-support.fs index 7e4fd05..4c6e1d1 100644 --- a/slof/fs/scsi-support.fs +++ b/slof/fs/scsi-support.fs @@ -123,11 +123,17 @@ CONSTANT scsi-length-sense-data \ ---------------------------------------- \ Forth Word: scsi-get-sense-data ( addr -- ascq asc sense-key ) \ ---------------------------------------- -: scsi-get-sense-data ( addr -- ascq asc sense-key ) +: scsi-get-sense-data ( addr -- ascq asc sense-key ) >r ( R: -- addr ) - r@ sense-data>ASCQ c@ ( ascq ) - r@ sense-data>ASC c@ ( ascq asc ) - r> sense-data>sense-key c@ 0f and ( ascq asc sense-key ) ( R: addr -- ) + r@ sense-data>response-code c@ 7f and 72 >= IF + r@ 3 + c@ ( ascq ) + r@ 2 + c@ ( ascq asc ) + r> 1 + c@ 0f and ( ascq asc sense-key ) + ELSE + r@ sense-data>ASCQ c@ ( ascq ) + r@ sense-data>ASC c@ ( ascq asc ) + r> sense-data>sense-key c@ 0f and ( ascq asc sense-key ) ( R: addr -- ) + THEN ; \ -------------------------------------------------------------------------- @@ -582,6 +588,28 @@ CONSTANT scsi-length-seek scsi-length-seek to scsi-param-size \ update CDB length ; +\ **************************************************************************** +\ CDROM media event stuff +\ **************************************************************************** + +STRUCT + /w FIELD media-event-data-len + /c FIELD media-event-nea-class + /c FIELD media-event-supp-class + /l FIELD media-event-data +CONSTANT scsi-length-media-event + +: scsi-build-get-media-event ( cdb -- ) + dup c erase ( cdb ) + 4a over c! ( cdb ) + 01 over 1 + c! + 10 over 4 + c! + 08 over 8 + c! + drop +; + + + \ *************************************************************************** \ SCSI-Utility: .sense-code \ *************************************************************************** @@ -712,7 +740,7 @@ CONSTANT scsi-length-seek \ *************************************************************************** \ utility that helps to ensure that parameters are set to valid values : scsi-supp-init ( -- ) - false to scsi-param-debug \ no debug strings + false to scsi-param-debug \ no debug strings h# 0 to scsi-param-size h# 0 to scsi-param-control \ common CDB control byte d# 0 to scsi-param-errors \ local errors (param limits) diff --git a/slof/fs/term-io.fs b/slof/fs/term-io.fs index 1ab9f94..cdd754a 100644 --- a/slof/fs/term-io.fs +++ b/slof/fs/term-io.fs @@ -57,6 +57,7 @@ \ this word will check what the current chosen input device is: \ - if it is a serial device, it will use serial-key? to check for available input \ - if it is a keyboard, it will check if the "key-available?" method is implemented (i.e. for usb-keyboard) and use that +\ - if it's an hv console, use hvterm-key? \ otherwise it will always return false : term-io-key? ( -- true|false ) s" stdin" get-chosen IF @@ -70,7 +71,9 @@ ELSE 1 - \ remove 1 from length to ignore null-termination char \ device_type found, check wether it is serial or keyboard - 2dup s" serial" str= IF 2drop serial-key? r> drop EXIT THEN \ call serial-key, cleanup return-stack, exit + 2dup s" serial" str= IF + 2drop serial-key? r> drop EXIT + THEN \ call serial-key, cleanup return-stack, exit 2dup s" keyboard" str= IF 2drop ( ) \ keyboard found, check for key-available? method, execute it or return false diff --git a/slof/lowmem.S b/slof/lowmem.S index 3f99320..9aaa9f7 100644 --- a/slof/lowmem.S +++ b/slof/lowmem.S @@ -20,10 +20,12 @@ _start: /* check if Master / Slave *****************/ /* Master will go to XVECT_M_HANDLER */ /* Slave will go to XVECT_S_HANDLER */ +#ifdef SECONDARY_CPUS_STOPPED ld r3,XVECT_S_HANDLER(0) mfspr r0, PIR cmpwi r0, 0 bne 0f +#endif ld r3,XVECT_M_HANDLER(0) 0: mtctr r3 @@ -45,14 +47,14 @@ _start: /* it traps, and with what register values etc. */ // b $ - mtsprg 0, r0 + mtsprg 0,r0 mfctr r0 mtsprg 2,r0 mflr r0 mtsprg 3,r0 ld r0, XVECT_M_HANDLER(0) mtctr r0 - li r0, \i + li r0,\i bctr .endr @@ -33,6 +33,8 @@ /* fill in handler address */ /* this only works if paflof is running below 4GB */ + mfmsr r0 + mtsrr1 r0 lis r3, _slof_text@h ori r3, r3, _slof_text@l ld r3, 0(r3) diff --git a/slof/paflof.c b/slof/paflof.c index 343d623..62f47de 100644 --- a/slof/paflof.c +++ b/slof/paflof.c @@ -26,6 +26,9 @@ #define LAST_ELEMENT(x) x[sizeof x / sizeof x[0] - 1] +/* Hack to get around static inline issues */ +#include "../lib/libhvcall/libhvcall.h" + unsigned long fdt_start; unsigned long romfs_base; unsigned long epapr_magic; diff --git a/slof/ppc64.c b/slof/ppc64.c index 8ad828c..20d9270 100644 --- a/slof/ppc64.c +++ b/slof/ppc64.c @@ -56,19 +56,21 @@ call_c(cell arg0, cell arg1, cell arg2, cell entry) : "=r" (r3) : "r" (r3), "r" (r4), "r" (r5), "r" (r6) : "ctr", "r6", "r7", "r8", "r9", "r10", "r11", - "r12", "r13", "r31"); + "r12", "r13", "r31", "lr", "cc"); return r3; } + long writeLogByte_wrapper(long x, long y) { unsigned long result; - set_ci(); + SET_CI; result = writeLogByte(x, y); - clr_ci(); + CLR_CI; + return result; } diff --git a/slof/ppc64.code b/slof/ppc64.code index 620446c..49dc863 100644 --- a/slof/ppc64.code +++ b/slof/ppc64.code @@ -25,6 +25,7 @@ PRIM(RX_X40) GET_XONG1; SET_CI; GET_XONG2; CLR_CI; GET_XONG3; MIRP PRIM(RX_X21) PUT_XONG1; SET_CI; PUT_XONG2; CLR_CI; MIRP // 970-specific CPU registers. +// Don't use on P7 ! PRIM(HID0_X21) unsigned long hid0 = TOS.u; asm volatile("sync ; mtspr 1008,%0 ; mfspr %0,1008 ; mfspr %0,1008 ; mfspr %0,1008 ; mfspr %0,1008 ; mfspr %0,1008 ; mfspr %0,1008" : "+r"(hid0)); diff --git a/slof/ppc64.h b/slof/ppc64.h index 2e9d90c..59a1b90 100644 --- a/slof/ppc64.h +++ b/slof/ppc64.h @@ -16,8 +16,13 @@ #define PAGE_SIZE 4096 #define HEAP_SIZE 0x800000 +#ifdef CPU_PPC970 #define SET_CI set_ci() #define CLR_CI clr_ci() +#else +#define SET_CI +#define CLR_CI +#endif // The big Forth source file that contains everything but the core engine. // We include it as a hunk of data into the C part of SLOF; at startup |