--- sos.test2/lib/nfs/nfsrpc.c 2004-07-29 16:27:11.000000000 +1000 +++ sos.nettest/lib/nfs/nfsrpc.c 2004-09-07 12:15:34.000000000 +1000 @@ -105,7 +105,7 @@ if (ret == 0) { debug( "mount call failed :(\n" ); - return 0; + return 1; } /* now we do some stuff :) */ @@ -113,7 +113,7 @@ if (status != 0) { debug( "Could not mount %s!\n", dir ); - return 0; + return 1; } getfrombuf(ret, (char*) pfh, sizeof(struct cookie)); --- sos.test2/sos/hardware.c 2004-07-29 16:27:07.000000000 +1000 +++ sos.nettest/sos/hardware.c 2004-09-06 16:40:28.000000000 +1000 @@ -1,8 +1,8 @@ /**************************************************************************** * - * $Id: hardware.c,v 1.1 2003/08/06 22:52:04 benjl Exp $ + * $Id: hardware.c,v 1.2 2003/09/10 11:44:38 benjl Exp $ * - * Description: Device driver and TCP/IP initialisation for SOS + * Description: Device driver initialisation for SOS * * Author: Ben Leslie * @@ -10,21 +10,36 @@ #include #include +#include +#include #include +#include +#include +#include #include "hardware.h" +#include "frames.h" struct serial *serial; +struct tulip *tulip; -/* - Should be called at startup to initialise the U4600 hardware -*/ +static void scan_pci(struct chipset *cs); + +#define TULIP_VENDOR 0x1011 +#define TULIP_DEVICE 0x14 + +/* Should be called at startup to initialise the U4600 hardware */ void hardware_init(void) { + struct chipset *cs; + bus_space_t space[2]; bs_seq sserial; + /* Initialise the chipset driver*/ + cs = gt_init(NULL); + /* Ensure the serial device memory is mapped in */ map_physical(NULL, (void*) 0x1c800000, 0x1000); @@ -40,4 +55,118 @@ /* Register an interrupt handler for the serial driver */ register_cpu_interrupt_handler(NULL, 4, serial_interrupt_handler, serial); + + /* Scan the PCI bus for valid drivers */ + scan_pci(cs); +} + +/* Find the position of the first zero bit in a word */ +static inline unsigned long +ffz(unsigned long word) +{ + unsigned long i; + + for (i = 0; i < 64; i++) + if ((word & (1UL << i)) == 0UL) + return i; + assert(!"Not possible"); +} + +/* Load a specific device driver */ +static void +load_pci(struct chipset *cs, int bus, int device, int function) +{ + uint32_t bar[6]; + uint32_t size[6]; + uint16_t vendor_num, device_num; + int i; + int irq; + bs_seq busspaces; + bus_space_t spaces[6]; + exec_handle_t handle; + + busspaces.c = 0; + busspaces.v = spaces; + + vendor_num = cs->ops->conf_read_16(cs->pvt, bus, device, function, 0); + device_num = cs->ops->conf_read_16(cs->pvt, bus, device, function, 2); + + /* + Test if we have a device driver for this device + + Currently we only have one driver, the tulip driver. So the test + is very straight forward . + + If we were a more sophisticated OS we would have to lookup + registered device drivers or something. + */ + if (vendor_num == TULIP_VENDOR && device_num == TULIP_DEVICE) { + l4e_printf("Found tulip card\n"); + } else { + return; + } + + for (i=0; i < 6; i++) { + int reg = 16+(i*4); + bar[i] = cs->ops->conf_read_32(cs->pvt, bus, device, + function, reg); + cs->ops->conf_write_32(cs->pvt, bus, device, function, + reg, (uint32_t)-1); + size[i] = cs->ops->conf_read_32(cs->pvt, bus, device, + function, reg); + cs->ops->conf_write_32(cs->pvt, bus, device, function, + reg, bar[i]); + } + + for (i = 0; i < 6; i++) { + uint32_t tmp_size = 0; + int io = 0; + if (bar[i] == 0) continue; + + io = size[i] & 0x1; + + if (io) { + bus_space_t iospace; + size[i] &= ~0x1L; + tmp_size = 1 << ffz(~size[i]); + + iospace = cs->ops->pci_iospace_map(cs->pvt, + (void*) (bar[i] & + ~(0x1L)), + tmp_size, 0); + busspaces.v[busspaces.c++] = iospace; + } + } + + irq = cs->ops->conf_read_8(cs->pvt, bus, device, function, 60); + + tulip = tulip_init(busspaces, NULL, NULL); + + /* Register the interrupt for the driver */ + handle.function = (void*) tulip_interrupt_handler; + handle.data = tulip; + cs->ops->pci_register_interrupt(cs->pvt, irq, handle); +} + +/* Scan the PCI bus for devices */ +static void +scan_pci(struct chipset *cs) +{ + uint16_t vendor, device; + int i; + + /* There are up to sixteen devices on the PCI bus. We get the + device and vendor ID for each one. If the vendor id is -1 + there is no device there so we skip it. Otherwise we try to + load a driver for it */ + for(i=0; i < 16; i++) { + /* We read the vendor and device register for this + given device */ + vendor = cs->ops->conf_read_16(cs->pvt, 0, i, 0, 0); + device = cs->ops->conf_read_16(cs->pvt, 0, i, 0, 2); + if (vendor != 0xffff) { + /* Load a driver for this device */ + load_pci(cs, 0, i, 0); + } + } } --- sos.test2/sos/hardware.h 2004-07-29 16:27:07.000000000 +1000 +++ sos.nettest/sos/hardware.h 2004-09-06 16:40:43.000000000 +1000 @@ -1,2 +1,3 @@ void hardware_init(void); extern struct serial *serial; +extern struct tulip *tulip; --- sos.test2/sos/main.c 2004-09-07 13:19:19.000000000 +1000 +++ sos.nettest/sos/main.c 2004-09-07 12:16:57.000000000 +1000 @@ -20,6 +20,7 @@ #include "frames.h" #include "pager.h" #include "hardware.h" +#include "network.h" #define HEAP_SIZE (1 * 1024 * 1024) /* 1 MB heap */ @@ -99,6 +100,9 @@ /* Initialise the u4600 hardware */ hardware_init(); + /* Initialise the network */ + network_init(); + /* Get access to the dit header */ dhdr = dite_gethdr(); assert(dhdr != NULL); --- sos.test2/sos/network.c 2004-07-29 16:27:07.000000000 +1000 +++ sos.nettest/sos/network.c 2004-09-07 13:46:31.000000000 +1000 @@ -22,6 +22,13 @@ struct cookie mnt_point; +/* This is the directory on the NFS server (asyst09) that will be mounted + * for your file system. Feel free to create a subdirectory for yourself/group + * to put your files in. + * Watch out for swap file collisions with your partner! :) + */ +#define NFS_DIR "/tftpboot" + void network_init(void) { @@ -43,7 +50,27 @@ /* This is setup for the MIPS box. If you are using sulima then you should user the 192.168.2.0 network */ IP4_ADDR(&gw, 192,168,1,1); - IP4_ADDR(&ipaddr, 192,168,1,2); + + /* FIXME: Make sure this IP is right for your group! + * PMON ip addresses for the machines are of the form: + * 192.168.1. + * + * Because you will be most likely changing machines, you can use + * static addresses of the form: + * 192.168.1.1 + * and + * 192.168.1.2 + * + * This allows you to have an IP per partner in your group. + * One IP for group 2 would be 192.168.1.102, group 12 would have + * 192.168.1.112, etc. + * + * If you do not have a partner/group number, or you would like + * more IP addresses for some reason, email the class account. + */ +#error Fix the IP address and read the big comment + IP4_ADDR(&ipaddr, 192,168,1,100); + IP4_ADDR(&netmask, 255,255,255,0); /* Setup the network interface */ @@ -76,5 +103,9 @@ mnt_get_export_list(); /* Mount aos_nfs */ - mnt_mount("aos_nfs", &mnt_point); + r = mnt_mount( NFS_DIR, &mnt_point); + if( r != 0 ) + l4e_printf( "Error mounting path '" NFS_DIR "'!\n" ); + else + l4e_printf( "Successfully mounted '" NFS_DIR"'\n" ); }