mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
This is odd, but try again.
Comitting IP checksum code, and its usage in linuxbios table creation. Mods to the dts, so that the device ops for the domain are set to the proper structure. This change is important. It gets rid of the obscure, confusing use of the enable_dev function to pick the right ops for a device. It makes the ops initilization very clear at the top level, in the dts. This has been tested and works, linux boots on Bochs under this version. Signed-off-by: Ronald G. Minnich <rminnich@gmail.com> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@191 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
ff7df4f7ad
commit
b41e38e4a2
7 changed files with 79 additions and 20 deletions
|
@ -108,7 +108,7 @@ $(obj)/stage0.init: $(STAGE0_OBJ)
|
|||
#
|
||||
|
||||
STAGE2_LIB_OBJ = $(obj)/stage2.o $(obj)/clog2.o $(obj)/mem.o $(obj)/malloc.o \
|
||||
$(obj)/tables.o $(obj)/delay.o
|
||||
$(obj)/tables.o $(obj)/delay.o $(obj)/compute_ip_checksum.o
|
||||
STAGE2_ARCH_X86_OBJ = $(obj)/archtables.o $(obj)/linuxbios_table.o $(obj)/udelay_io.o
|
||||
STAGE2_ARCH_X86_OBJ += $(obj)/pci_ops_auto.o $(obj)/pci_ops_conf1.o $(obj)/pci_ops_conf2.o
|
||||
STAGE2_MAINBOARD_OBJ = $(obj)/mainboard.o
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
//#include <ip_checksum.h>
|
||||
#include <ip_checksum.h>
|
||||
#include <string.h>
|
||||
//#include <cpu/cpu.h>
|
||||
//#include <boot/tables.h>
|
||||
|
@ -229,9 +229,9 @@ unsigned long lb_table_fini(struct lb_header *head)
|
|||
}
|
||||
lb_reserve_table_memory(head);
|
||||
first_rec = lb_first_record(head);
|
||||
head->table_checksum = 0; //compute_ip_checksum(first_rec, head->table_bytes);
|
||||
head->table_checksum = compute_ip_checksum(first_rec, head->table_bytes);
|
||||
head->header_checksum = 0;
|
||||
head->header_checksum = 0; //compute_ip_checksum(head, sizeof(*head));
|
||||
head->header_checksum = compute_ip_checksum(head, sizeof(*head));
|
||||
printk(BIOS_DEBUG,"Wrote linuxbios table at: %p - %p checksum %lx\n",
|
||||
head, rec, head->table_checksum);
|
||||
return (unsigned long)rec;
|
||||
|
|
8
include/ip_checksum.h
Normal file
8
include/ip_checksum.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef IP_CHECKSUM_H
|
||||
#define IP_CHECKSUM_H
|
||||
|
||||
unsigned long compute_ip_checksum(void *addr, unsigned long length);
|
||||
unsigned long add_ip_checksums(unsigned long offset, unsigned long sum, unsigned long new);
|
||||
|
||||
#endif /* IP_CHECKSUM_H */
|
||||
|
53
lib/compute_ip_checksum.c
Normal file
53
lib/compute_ip_checksum.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include <stdint.h>
|
||||
#include <ip_checksum.h>
|
||||
|
||||
unsigned long compute_ip_checksum(void *addr, unsigned long length)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
volatile union {
|
||||
uint8_t byte[2];
|
||||
uint16_t word;
|
||||
} value;
|
||||
unsigned long sum;
|
||||
unsigned long i;
|
||||
/* In the most straight forward way possible,
|
||||
* compute an ip style checksum.
|
||||
*/
|
||||
sum = 0;
|
||||
ptr = addr;
|
||||
for(i = 0; i < length; i++) {
|
||||
unsigned long value;
|
||||
value = ptr[i];
|
||||
if (i & 1) {
|
||||
value <<= 8;
|
||||
}
|
||||
/* Add the new value */
|
||||
sum += value;
|
||||
/* Wrap around the carry */
|
||||
if (sum > 0xFFFF) {
|
||||
sum = (sum + (sum >> 16)) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
value.byte[0] = sum & 0xff;
|
||||
value.byte[1] = (sum >> 8) & 0xff;
|
||||
return (~value.word) & 0xFFFF;
|
||||
}
|
||||
|
||||
unsigned long add_ip_checksums(unsigned long offset, unsigned long sum, unsigned long new)
|
||||
{
|
||||
unsigned long checksum;
|
||||
sum = ~sum & 0xFFFF;
|
||||
new = ~new & 0xFFFF;
|
||||
if (offset & 1) {
|
||||
/* byte swap the sum if it came from an odd offset
|
||||
* since the computation is endian independant this
|
||||
* works.
|
||||
*/
|
||||
new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00);
|
||||
}
|
||||
checksum = sum + new;
|
||||
if (checksum > 0xFFFF) {
|
||||
checksum -= 0xFFFF;
|
||||
}
|
||||
return (~checksum) & 0xFFFF;
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
domain0{
|
||||
enabled;
|
||||
config="northbridge,intel,i440bxemulation";
|
||||
ops="default_pci_ops_dev";
|
||||
ops="i440bxemulation_pcidomainops";
|
||||
pcidomain = "0";
|
||||
device0,0{
|
||||
enabled;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
extern struct chip_operations northbridge_intel_i440bxemulation_ops;
|
||||
extern struct device_operations i440bxemulation_pcidomainops;
|
||||
|
||||
struct northbridge_intel_i440bx_config
|
||||
{
|
||||
|
|
|
@ -27,29 +27,18 @@
|
|||
#include "config.h"
|
||||
#include "i440bx.h"
|
||||
|
||||
/* This is the starting point. */
|
||||
struct device_operations i440bxemulation_pcidomainops;
|
||||
static void i440bxemulation_enable_dev(struct device *dev)
|
||||
{
|
||||
printk(BIOS_INFO, "%s: \n", __FUNCTION__);
|
||||
/* just a test here. ... we don't want to do this in real life */
|
||||
dev->ops = &i440bxemulation_pcidomainops;
|
||||
/* Set the operations if it is a special bus type */
|
||||
/*
|
||||
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
|
||||
dev->ops = &pci_domain_ops;
|
||||
pci_set_method(dev);
|
||||
}
|
||||
*/
|
||||
printk(BIOS_INFO, "%s: Done.\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
struct chip_operations northbridge_intel_i440bxemulation_ops = {
|
||||
.name="Intel 440BX Northbridge Emulation",
|
||||
.enable_dev = i440bxemulation_enable_dev,
|
||||
};
|
||||
|
||||
/* Here are the ops for 440BX as a PCI domain. */
|
||||
/* a PCI domain contains the I/O and memory resource address space below it. */
|
||||
/* Currently, the only functions in here are for the domain. If device functions are needed,
|
||||
* they will come later.
|
||||
*/
|
||||
|
||||
static void pci_domain_read_resources(struct device * dev)
|
||||
{
|
||||
|
@ -103,6 +92,14 @@ static unsigned int pci_domain_scan_bus(struct device * dev, unsigned int max)
|
|||
return max;
|
||||
}
|
||||
|
||||
/* here are the chip operations. These are for the chip-specific functions. */
|
||||
struct chip_operations northbridge_intel_i440bxemulation_ops = {
|
||||
.name="Intel 440BX Northbridge Emulation",
|
||||
.enable_dev = i440bxemulation_enable_dev,
|
||||
};
|
||||
|
||||
/* here are the operations for when the northbridge is running a pci domain. */
|
||||
/* see emulation/qemu-x86 for an example of how these are used. */
|
||||
struct device_operations i440bxemulation_pcidomainops = {
|
||||
.phase4_read_resources = pci_domain_read_resources,
|
||||
.phase4_set_resources = pci_domain_set_resources,
|
||||
|
|
Loading…
Add table
Reference in a new issue