When I tried to abort the net-snk TFTP boot by pressing ESC
a couple of times, I sometimes noticed that SLOF ended up
with a negative stack depth counter. After doing some closer
investigation, I disovered that the problem can be reproduced
by simply pressing "ESC ESC RETURN" at the SLOF prompt.
The problem is in the code in accept.fs: If an ESC character is
found in the input stream, the "handle-ESC" function is called.
This reads in the next input character with "key", and if it
does not match 0x5b or 0x4f, it calls "handle-meta" for further
handling. handle-meta consumes the value from "key" on the stack
to use it as an index into a jump table, thus the stack is empty
now. If the index was a 0x1b (due to the second ESC character),
the function handle-CSI is called. But that function expects
another value as index for a jump table on the stack, and since
the stack was already empty, we end up with a negative stack
depth here.
Apparently, handle-meta should call a function instead that
uses "key" to get another character from the input stream,
before calling the handle-CSI function.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Tested-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
As this was done at byte granularity, erasing complete nvram(64K
default) took a lot of time. To reduce the number of rtas call per byte
write which is expensive, the erase is done at one shot using the
nvram_buffer that is initiated during the nvram_init call for
RTAS_NVRAM.
After this patch there is ~450msec improvement during boot. Default qemu
booting does not provide file backed nvram, so every boot there would be
full erase of 64K.
Before this patch:
real 0m2.214s
user 0m0.015s
sys 0m0.006s
real 0m2.222s
user 0m0.014s
sys 0m0.005s
real 0m2.201s
user 0m0.010s
sys 0m0.005s
After this patch:
real 0m1.762s
user 0m0.014s
sys 0m0.006s
real 0m1.773s
user 0m0.011s
sys 0m0.004s
real 0m1.754s
user 0m0.013s
sys 0m0.005s
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The whole ethernet frame can be up to 1518 bytes including the ethernet
header. So this value should be used instead of 1500 when the whole
ethernet packet is affected. Since we've already got a nice define
for this value, use ETH_MTU_SIZE where it is appropriate.
This patch also removes a "memset(n->eth_frame, 0, 1500)" in send_ipv6()
to get rid of the magic value 1500 there -- it can be removed since
the whole ethernet packet is filled into the buffer right after the
memset, so there are no gaps that should be cleared first.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
When ip6addr_add() is called for the first time, both the first_ip6
and the last_ip6 pointer are not initialized yet, i.e. contain NULL.
So writing to "last_ip6->next" is a bad idea here. Fix it so that
this value is only written when the function is not called for the
first time.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The set_ipv6_address() function calls ip6_create_ll_address() to
get a link-local address. The latter function uses malloc to create
a buffer for composing that address, and returns the corresponding
poniter to the caller. However, set_ipv6_address() does not free
that buffer again, so the allocated memory is lost.
Since set_ipv6_address() already allocated space for the new IPv6
address anyway, let's fix this issue by passing the buffer from
set_ipv6_address() to ip6_create_ll_address() instead, so that
ip6_create_ll_address() does not have to allocate memory at all.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The IPv6 code uses malloc in a couple of places to allocate the memory
for a struct. But it does not properly initializes all members of the
struct after the allocation, so the uninitialized members might contain
random data. So we should better clear the whole memory for those
structs to make sure we do not run into some hard-to-reproduce random
problems later.
Reported-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The "struct neighbor *n" pointer in send_ipv6() can be NULL, e.g.
when we're sending to multicast addresses or to a server that sits
behind a router (since we do not have an entry in the neighbor cache
in this case).
However, the final code in send_ipv6() is always using n->eth_frame
to assemble the ethernet packet, and thus silently writes the data
into the low memory (which happens unnoticed because SLOF does not
use the MMU for memory protection).
This issue is now fixed by using a separate buffer for assembling
those ethernet packets instead. The block for using the router's
MAC address is also moved out of the block that is supposed to handle
the unicast transfers, so that we do not accidentially end up in the
neighbour solicitation code here (which also relies on n != NULL).
Reported-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
ping was failing for machine across the subnet with statically assinged
IP address. The parsed gateway address was ignored in the stack because
the router variable was not set.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The current ping command does not take netmask as argument, updated the
ping command to take "client-ip/nn" format ip address.
Add routine to return netmask(class based), when not provided by user.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Current handling of the keyboard polling was very slow and
keys were getting dropped. Done following for fixing this:
* Use multiple buffers per TRB
* Allocate buffers in xhci according to the number of TRBS.
This reduces the delay of key? processing by getting rid of wait in
the polling routine.
Reported-by: Dinar Valeev <k0da@opensuse.org>
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Tested-by: Dinar Valeev <k0da@opensuse.org>
Tested-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
A memory barrier was missing after updating the trb details.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The old netflash code is not available in the net-snk anymore,
so it does not make sense to keep the Forth wrapper around.
Anyway, "update-flash -f net:..." can be used nowadays instead.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
These words were required in the very early days of SLOF when
"boot net" / "load net" was not working yet. Nowadays, they
are pretty useless and thus can be removed.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
These functions are only used by some ancient js2x code,
so move them to that folder accordingly.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The huge-tftp-load variable is only needed by the obp-tftp
package, so it should reside there, not in base.fs
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
These functions were only used by the SMS code that has been
removed already a while ago. It does not make sense anymore
to parse them during each boot, and even if we'd still need
them, they should not reside in base.fs. Since we're currently
do not need them anymore, let's simply remove them completely.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Simple cosmetical fix - some lines were indented with spaces instead
of tabs. Change it to be in line with the coding conventions.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Allow the new little-endian ring format for the 9p driver, too,
just like it has already been done for the other virtio devices.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The virtio-9p devices currently show up as "unknown-legacy-device"
in the device tree. We've got a driver for this device, so it is
certainly not "unknown", i.e. let's use a better name here instead.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Some parts of the IPv6 code are still indented with spaces. Let's
use tabs instead as mandated by the SLOF coding conventions.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The send_ipv6() function should return after doing NDP, since either
the queued packet got send out during handle_na() already, or it has
been stored to be sent out later (once the neighbor advertisment has
been received). If we don't return here, the code runs into the final
send_ether() here later, which then sends out the packet a second time.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The code in send_ipv6() currently basically looks like this:
uint8_t *mac_addr, mac[6];
mac_addr = mac;
...
n = find_neighbor (&ip_dst);
if (ip6_is_multicast (&ip_dst)) {
mac_addr = ip6_to_multicast_mac (&ip_dst, mac);
}
else {
// Check if the MAC address is already cached
if (n) {
if (memcmp(n->mac, null_mac, ETH_ALEN) != 0)
memcpy (mac_addr, &(n->mac), ETH_ALEN);
/* XXX */
}
...
}
...
fill_ethhdr (n->eth_frame, htons(ETHERTYPE_IPv6), get_mac_address(),
mac_addr);
That means mac_addr initially points to the uninitialized mac[6]
array on the stack. Now if there was already an entry in the neighbor
cache, but the MAC address has not been determined yet, that
uninitialized array could be used as final MAC address for fill_ethhdr()
(since there is no "else" path at the spot marked with XXX above),
resulting in random data in the MAC address field of the ethernet packet.
Let's fix this issue by letting mac_addr point to the null_mac by
default instead, so that it never points to invalid data. Also
rename mac[6] to mc_mac[6] to make it clear that this array is
only used for storing the multicast mac address.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The network boot over IPv6 currently fails if the TFTP server
is not in the same subnet as the SLOF client. In that case we
have to fill in the MAC address of a router into our packets
to get them to the right place.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
There is currently only an unusable stub for the sms menu in SLOF.
It does not make much sense to parse this defunc code each time
we boot, that only wastes time and space in the boot rom image.
So let's simply remove these sms menu remainders for now.
Note: This patch also touches one line in OF.fs to make sure that
the dependencies for this file are properly regenerated (so we
avoid to force everybody to do a 'make distclean' afterwards).
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
With commit aa9566d2e(virtio-net: move setup-mac to the open routine)
local-mac-address property started getting set during open routine. So
the netboot workflow was addressed. This was required as the device
needs to be probed before reading, after virtio 1.0 changes.
While boot from the disk and grub is set to get kernel over network, it
breaks. As grub looks for local-mac-address property first, which is not
there. Fix this by creating an instance and closing it. setup-mac in the
open will populate the local-mac-addres property
Reported-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Using backspaces after printing out the checkpoint numbers is fine
when printing to terminals. But if the output of SLOF is placed
into a log file instead, this can confuse certain readers like
Firefox to interpret the log file as a binary file instead of text.
To avoid this problem, we can also use '\r' to move the cursor
back to the beginning - this should be fine since the checkpoints
are always printed at the beginning of a line anyway. And '\r' is
then interpreted as normal text, not as a potential binary file byte.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The "read" function of the dev-null device currently claims that
the same amount of bytes has been read as input bytes have been
requested. This causes grub to hang forever at the boot selection
menu, since grub then thinks that there's a continuous stream of input
data. If nothing has been read (which is always the case for the
dev-null device), the "read" function should simply return 0 instead.
Then grub also boots properly again after the typical short timeout.
Reported-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
With the removal of dupicate strtoip in patch "dhcp: Remove duplicated
strtoip()" (commit 896e31da2c), we get
following warnings messages:
dhcp.c: In function ‘dhcpv4’:
dhcp.c:215:16: warning: pointer targets in passing argument 1 of ‘strtoip’ differ in signedness [-Wpointer-sign]
if (!strtoip(dhcp_tftp_name, (uint8_t *)&dhcp_tftp_ip)) {
^
In file included from dhcp.c:51:0:
../netapps/args.h:20:5: note: expected ‘const char *’ but argument is of type ‘int8_t * {aka signed char *}’
int strtoip(const char *, char[4]);
^
dhcp.c:215:32: warning: pointer targets in passing argument 2 of ‘strtoip’ differ in signedness [-Wpointer-sign]
if (!strtoip(dhcp_tftp_name, (uint8_t *)&dhcp_tftp_ip)) {
^
In file included from dhcp.c:51:0:
../netapps/args.h:20:5: note: expected ‘char *’ but argument is of type ‘uint8_t * {aka unsigned char *}’
int strtoip(const char *, char[4]);
^
There were unnecessary typecasts which could be removed by declaring
dhcp_tftp_name and dhcp_filename. Along with this, change the dns_get_ip
signature as well to reduce typecast.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Also add a device file for non-transitional pci device id: 0x1048
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Fix the initialization of the virtqueues. It was always initializing the
first virtqueue, while the objective is to init all the virtqueues.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Also add a device file for non-transitional pci device id: 0x1041
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Also add a device file for non-transitional pci device id: 0x1042
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
To avoid cluttering the driver code with modern/legacy code introduce
virtio_cpu_to_modern{16,32,64} and virtio_modern{16,32,64}_to_cpu in a
separate header file virtio-internal.h.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Suggested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Introduce parsing routines for virtio capabilities. This would also
determine whether we need to function in legacy mode or virtio 1.0.
Update routine to start using the base address from the updated legacy
structure.
With the removal for base address setting in the Forth code and most of
the device setup happening in C code, code in virtio.fs is redundant.
Remove virtio.fs and move the allocation of the virtio_device structure
to the C code instead of the Forth code in individual files. Also, drop
the packed attribute for the virtio_{device,cap} structure. The
structure is not shared anymore.
Drivers need to negotiate the 1.0 feature capability before starting to
use 1.0. Disable it in all the drivers until 1.0 is enabled.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
With virtio 1.0, there feature negotiation step needs to be completed
before starting to notify the device.
This includes following steps:
* Read host supported features
* Check if virtio 1.0 is supported
* Set guest supported features
* Read host features and compare with the guest features.
* Write FEATURES_OK and check it back to confirm.
Add virtio_get_status supporting routine.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The new specification has a 64-bit feature register, change the
signature and update the routine to handle them.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Convert the following routines:
virtio_get_qsize
virtio_vring_desc
virtio_get_vring_avail
virtio_get_vring_used
virtio_set_status: also use it in device reset.
virtio_queue_notify
virtio_set_qaddr
virtio_{get,read}_config
virtio_fill_desc
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
64-bit fields are to be treated as two 32-bit fields, with low 32 bit
part followed by the high 32 bit part.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Traditionally, struct virtio_device is shared between SLOF and C code.
This still remains shared with the addition of virtio_cap structure as
well. Now both virtio_device and virtio_cap structures are shared.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
virtio device structure carries a type variable indicating whether
virtio is over PCI or VIO. While VIO is not there and no plan to
introduce other transport, there is no purpose of having this variable
around and checking for PCI.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
MAC reading should be done after the initialization of the device after
the features negotiation.
Adjust the open routine accordingly. There is no point in sending the
mac address to the virtionet_open. Change the signature. Also read the
mac address directly from the config space to remove the dependency of
getting the mac address from the open routine.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Size of the net_hdr_size is different in legacy and modern devices. This
helps in conversion of the driver to 1.0.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Using an array here is not necassary, simplifies the code for
readability.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Simplifies the driver code and is helpful for migration to virtio 1.0
enablement.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
The virtio_set_status lines were getting too long because of OR'ing the
status on the same line of the call. Moreover, going forward we need to
add FEATURES_OK status as well. The state progress is quite straight
forward, so use status variable instead. Code looks cleaner and can easily
make out the change in the state.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Enable virtio_fill_desc/fill_blk_hdr with legacy and modern mode for
further use
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
With the lack of the virtio_queue_init_vq routine, driver like
virtio-blk and virtio-9p had disabled device reset in the
initialization code. This helper will fix that problem, as the
initialization can be done after the device reset.
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>