Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pc-bios/s390-ccw: Add core files for the network bootloading program
This is just a preparation for the next steps: Add a makefile and a stripped down copy of pc-bios/s390-ccw/main.c as a basis for the network bootloader program, linked against the libc from SLOF already (which we will need for SLOF's libnet). The networking code is not included yet. Reviewed-by: Cornelia Huck <cohuck@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com> Message-Id: <1499863793-18627-10-git-send-email-thuth@redhat.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
- Loading branch information
1 parent
4bfd755
commit 3e4415a
Showing
3 changed files
with
192 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
|
||
SLOF_DIR := $(SRC_PATH)/roms/SLOF | ||
|
||
NETOBJS := start.o sclp.o virtio.o netmain.o libc.a | ||
|
||
LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include | ||
LIBNET_INC := -I$(SLOF_DIR)/lib/libnet | ||
|
||
NETLDFLAGS := $(LDFLAGS) -Ttext=0x7800000 | ||
|
||
$(NETOBJS): QEMU_CFLAGS += $(LIBC_INC) $(LIBNET_INC) | ||
|
||
s390-netboot.elf: $(NETOBJS) | ||
$(call quiet-command,$(CC) $(NETLDFLAGS) -o $@ $(NETOBJS),"BUILD","$(TARGET_DIR)$@") | ||
|
||
s390-netboot.img: s390-netboot.elf | ||
$(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,"STRIP","$(TARGET_DIR)$@") | ||
|
||
# libc files: | ||
|
||
LIBC_CFLAGS := $(QEMU_CFLAGS) $(LIBC_INC) $(LIBNET_INC) | ||
|
||
CTYPE_OBJS = isdigit.o isxdigit.o toupper.o | ||
%.o : $(SLOF_DIR)/lib/libc/ctype/%.c | ||
$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") | ||
|
||
STRING_OBJS = strcat.o strchr.o strcmp.o strcpy.o strlen.o strncmp.o strncpy.o \ | ||
strstr.o memset.o memcpy.o memmove.o memcmp.o | ||
%.o : $(SLOF_DIR)/lib/libc/string/%.c | ||
$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") | ||
|
||
STDLIB_OBJS = atoi.o atol.o strtoul.o strtol.o rand.o malloc.o free.o | ||
%.o : $(SLOF_DIR)/lib/libc/stdlib/%.c | ||
$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") | ||
|
||
STDIO_OBJS = sprintf.o vfprintf.o vsnprintf.o vsprintf.o fprintf.o \ | ||
printf.o putc.o puts.o putchar.o stdchnls.o fileno.o | ||
%.o : $(SLOF_DIR)/lib/libc/stdio/%.c | ||
$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") | ||
|
||
sbrk.o: $(SLOF_DIR)/slof/sbrk.c | ||
$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") | ||
|
||
LIBCOBJS := $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) sbrk.o | ||
|
||
libc.a: $(LIBCOBJS) | ||
$(call quiet-command,$(AR) -rc $@ $^,"AR","$(TARGET_DIR)$@") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* | ||
* S390 virtio-ccw network boot loading program | ||
* | ||
* Copyright 2017 Thomas Huth, Red Hat Inc. | ||
* | ||
* Based on the S390 virtio-ccw loading program (main.c) | ||
* Copyright (c) 2013 Alexander Graf <agraf@suse.de> | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. | ||
*/ | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <time.h> | ||
|
||
#include "s390-ccw.h" | ||
#include "virtio.h" | ||
|
||
extern char _start[]; | ||
|
||
char stack[PAGE_SIZE * 8] __attribute__((aligned(PAGE_SIZE))); | ||
IplParameterBlock iplb __attribute__((aligned(PAGE_SIZE))); | ||
|
||
static SubChannelId net_schid = { .one = 1 }; | ||
static uint64_t dest_timer; | ||
|
||
static uint64_t get_timer_ms(void) | ||
{ | ||
uint64_t clk; | ||
|
||
asm volatile(" stck %0 " : : "Q"(clk) : "memory"); | ||
|
||
/* Bit 51 is incremented each microsecond */ | ||
return (clk >> (63 - 51)) / 1000; | ||
} | ||
|
||
void set_timer(int val) | ||
{ | ||
dest_timer = get_timer_ms() + val; | ||
} | ||
|
||
int get_timer(void) | ||
{ | ||
return dest_timer - get_timer_ms(); | ||
} | ||
|
||
int get_sec_ticks(void) | ||
{ | ||
return 1000; /* number of ticks in 1 second */ | ||
} | ||
|
||
void panic(const char *string) | ||
{ | ||
sclp_print(string); | ||
for (;;) { | ||
disabled_wait(); | ||
} | ||
} | ||
|
||
static bool find_net_dev(Schib *schib, int dev_no) | ||
{ | ||
int i, r; | ||
|
||
for (i = 0; i < 0x10000; i++) { | ||
net_schid.sch_no = i; | ||
r = stsch_err(net_schid, schib); | ||
if (r == 3 || r == -EIO) { | ||
break; | ||
} | ||
if (!schib->pmcw.dnv) { | ||
continue; | ||
} | ||
if (!virtio_is_supported(net_schid)) { | ||
continue; | ||
} | ||
if (virtio_get_device_type() != VIRTIO_ID_NET) { | ||
continue; | ||
} | ||
if (dev_no < 0 || schib->pmcw.dev == dev_no) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
static void virtio_setup(void) | ||
{ | ||
Schib schib; | ||
int ssid; | ||
bool found = false; | ||
uint16_t dev_no; | ||
|
||
/* | ||
* We unconditionally enable mss support. In every sane configuration, | ||
* this will succeed; and even if it doesn't, stsch_err() can deal | ||
* with the consequences. | ||
*/ | ||
enable_mss_facility(); | ||
|
||
if (store_iplb(&iplb)) { | ||
IPL_assert(iplb.pbt == S390_IPL_TYPE_CCW, "IPL_TYPE_CCW expected"); | ||
dev_no = iplb.ccw.devno; | ||
debug_print_int("device no. ", dev_no); | ||
net_schid.ssid = iplb.ccw.ssid & 0x3; | ||
debug_print_int("ssid ", net_schid.ssid); | ||
found = find_net_dev(&schib, dev_no); | ||
} else { | ||
for (ssid = 0; ssid < 0x3; ssid++) { | ||
net_schid.ssid = ssid; | ||
found = find_net_dev(&schib, -1); | ||
if (found) { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
IPL_assert(found, "No virtio net device found"); | ||
} | ||
|
||
void main(void) | ||
{ | ||
sclp_setup(); | ||
sclp_print("Network boot starting...\n"); | ||
|
||
virtio_setup(); | ||
|
||
panic("Failed to load OS from network\n"); | ||
} |