From 075d79f6d4ee0725dd118cf291959221e7e681d8 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 8 Jan 2007 03:45:00 +0000 Subject: [PATCH] Checking in obsolete but working memory-scanning code just for the record --- src/arch/i386/drivers/bus/pxebus.c | 265 ++++++++--------------------- 1 file changed, 71 insertions(+), 194 deletions(-) diff --git a/src/arch/i386/drivers/bus/pxebus.c b/src/arch/i386/drivers/bus/pxebus.c index 7ad3b6aa..4876fa2a 100644 --- a/src/arch/i386/drivers/bus/pxebus.c +++ b/src/arch/i386/drivers/bus/pxebus.c @@ -1,3 +1,5 @@ +#if 0 + /* * Copyright (C) 2007 Michael Brown . * @@ -22,7 +24,10 @@ #include #include #include +#include +#include #include +#include /** @file * @@ -30,84 +35,6 @@ * */ -/** - * UNDI parameter block - * - * Used as the paramter block for all UNDI API calls. Resides in base - * memory. - */ -static union u_PXENV_ANY __data16 ( pxe_params ); -#define pxe_params __use_data16 ( pxe_params ) - -/** UNDI entry point */ -static SEGOFF16_t __data16 ( pxe_entry_point ); -#define pxe_entry_point __use_data16 ( pxe_entry_point ) - -/** - * Issue PXE API call - * - * @v pxe PXE device - * @v function API call number - * @v params PXE parameter block - * @v params_len Length of PXE parameter block - * @ret rc Return status code - */ -int pxe_call ( struct pxe_device *pxe, unsigned int function, - void *params, size_t params_len ) { - union u_PXENV_ANY *pxenv_any = params; - PXENV_EXIT_t exit; - int discard_b, discard_D; - int rc; - - /* Copy parameter block and entry point */ - assert ( params_len <= sizeof ( pxe_params ) ); - memcpy ( &pxe_params, params, params_len ); - pxe_entry_point = pxe->entry; - - /* Call real-mode entry point. This calling convention will - * work with both the !PXE and the PXENV+ entry points. - */ - __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t" - "pushw %%di\n\t" - "pushw %%bx\n\t" - "lcall *%c3\n\t" - "addw $6, %%sp\n\t" ) - : "=a" ( exit ), "=b" ( discard_b ), - "=D" ( discard_D ) - : "p" ( & __from_data16 ( pxe_entry_point ) ), - "b" ( function ), - "D" ( & __from_data16 ( pxe_params ) ) ); - - /* UNDI API calls may rudely change the status of A20 and not - * bother to restore it afterwards. Intel is known to be - * guilty of this. - * - * Note that we will return to this point even if A20 gets - * screwed up by the UNDI driver, because Etherboot always - * resides in an even megabyte of RAM. - */ - gateA20_set(); - - /* Copy parameter block back */ - memcpy ( params, &pxe_params, params_len ); - - /* Determine return status code based on PXENV_EXIT and - * PXENV_STATUS - */ - if ( exit == PXENV_EXIT_SUCCESS ) { - rc = 0; - } else { - rc = -pxenv_any->Status; - /* Paranoia; don't return success for the combination - * of PXENV_EXIT_FAILURE but PXENV_STATUS_SUCCESS - */ - if ( rc == 0 ) - rc = -EIO; - } - - return rc; -} - /** * Byte checksum * @@ -125,82 +52,6 @@ static uint8_t checksum ( void *data, size_t len ) { return sum; } -/** - * Get PXE device information for an instantiated device - * - * @v pxe PXE device - * @ret rc Return status code - */ -static int pxedev_get_instance_info ( struct pxe_device *pxe ) { - struct s_PXENV pxenv; - struct s_PXE ppxe; - struct s_PXENV_UNDI_GET_INFORMATION undi_info; - int rc; - - /* Determine entry point from PXENV+ structure */ - DBGC ( pxe, "PXE %p has PXENV+ structure at %04x:%04x\n", pxe, - pxe->pxenv.segment, pxe->pxenv.offset ); - copy_from_real ( &pxenv, pxe->pxenv.segment, pxe->pxenv.offset, - sizeof ( pxenv ) ); - if ( checksum ( &pxenv, sizeof ( pxenv ) ) != 0 ) { - DBGC ( pxe, "PXE %p bad PXENV+ checksum\n", pxe ); - return -EINVAL; - } - pxe->entry = pxenv.RMEntry; - - /* If API version is 2.1 or greater, use the !PXE structure instead */ - if ( pxenv.Version >= 0x0201 ) { - pxe->ppxe = pxenv.PXEPtr; - DBGC ( pxe, "PXE %p has !PXE structure at %04x:%04x\n", pxe, - pxe->ppxe.segment, pxe->ppxe.offset ); - copy_from_real ( &ppxe, pxe->ppxe.segment, pxe->ppxe.offset, - sizeof ( ppxe ) ); - if ( checksum ( &pxenv, sizeof ( pxenv ) ) != 0 ) { - DBGC ( pxe, "PXE %p bad !PXE checksum\n", pxe ); - return -EINVAL; - } - pxe->entry = ppxe.EntryPointSP; - } - - DBGC ( pxe, "PXE %p using entry point at %04x:%04x\n", pxe, - pxe->entry.segment, pxe->entry.offset ); - - /* Get device information */ - memset ( &undi_info, 0, sizeof ( undi_info ) ); - if ( ( rc = pxe_call ( pxe, PXENV_UNDI_GET_INFORMATION, &undi_info, - sizeof ( undi_info ) ) ) != 0 ) { - DBGC ( pxe, "PXE %p could not retrieve UNDI information: %s\n", - pxe, strerror ( rc ) ); - return rc; - } - memcpy ( pxe->hwaddr, undi_info.PermNodeAddress, - sizeof ( pxe->hwaddr ) ); - pxe->irq = undi_info.IntNumber; - pxe->rom_segment = undi_info.ROMAddress; - - return 0; -} - -/** - * Register PXE device - * - * @v pxe PXE device - * @ret rc Return status code - */ -static int register_pxedev ( struct pxe_device *pxe ) { - int rc; - - DBGC ( pxe, "PXE %p registering\n", pxe ); - - /* Register as an UNDI driver */ - if ( ( rc = undi_probe ( pxe ) ) != 0 ) - return rc; - - /* Add to device hierarchy and return */ - list_add ( &pxe->dev.siblings, &pxe->dev.parent->children ); - return 0; -} - /** * Unregister a PXE device * @@ -224,47 +75,74 @@ static void pxebus_remove ( struct root_device *rootdev ); * find. */ static int pxebus_probe ( struct root_device *rootdev ) { - struct pxe_device *pxe; - uint16_t signature; - uint16_t pxenv_segment; - uint16_t pxenv_offset; + struct pxe_device *pxe = NULL; + struct s_PXENV pxenv; + struct s_PXE ppxe; + uint16_t fbms; + unsigned int segment; + unsigned int undi_cs; int rc; - /* PXE installation check */ - __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" - "int $0x1a\n\t" - "jnc 1f\n\t" - "xorw %%ax, %%ax\n\t" - "\n1:\n\t" - "movw %%es, %%dx\n\t" ) - : "=a" ( signature ), "=b" ( pxenv_offset ), - "=d" ( pxenv_segment ) - : "a" ( 0x5650 ) ); - if ( signature != 0x564e ) { - DBG ( "No pixies found\n" ); - return 0; + /* Scan through allocated base memory for PXENV+ structure */ + get_real ( fbms, BDA_SEG, BDA_FBMS ); + for ( segment = ( fbms << 6 ) ; segment < 0xa000 ; segment++ ) { + + /* Verify PXENV+ signature and checksum */ + copy_from_real ( &pxenv, segment, 0, sizeof ( pxenv ) ); + if ( memcmp ( pxenv.Signature, "PXENV+", 6 ) != 0 ) + continue; + DBG ( "Found PXENV+ signature at %04x0\n", segment ); + if ( checksum ( &pxenv, sizeof ( pxenv ) ) != 0 ) { + DBG ( "...bad checksum\n" ); + continue; + } + + /* Allocate PXE device structure */ + pxe = malloc ( sizeof ( *pxe ) ); + if ( ! pxe ) { + rc = -ENOMEM; + goto err; + } + memset ( pxe, 0, sizeof ( *pxe ) ); + + /* Add to device hierarchy */ + pxe->dev.parent = &rootdev->dev; + INIT_LIST_HEAD ( &pxe->dev.children ); + list_add ( &pxe->dev.siblings, &rootdev->dev.children ); + + /* Populate PXE device structure */ + undi_cs = pxenv.UNDICodeSeg; + pxe->pxenv.segment = undi_cs; + pxe->pxenv.offset = ( ( segment - undi_cs ) << 4 ); + DBGC ( pxe, "PXE %p has PXENV+ structure at %04x:%04x\n", + pxe, pxe->pxenv.segment, pxe->pxenv.offset ); + pxe->entry = pxenv.RMEntry; + if ( pxenv.Version >= 0x0201 ) { + pxe->ppxe = pxenv.PXEPtr; + copy_from_real ( &ppxe, pxe->ppxe.segment, + pxe->ppxe.offset, sizeof ( ppxe ) ); + if ( ( memcmp ( ppxe.Signature, "!PXE", 4 ) == 0 ) && + ( checksum ( &ppxe, sizeof ( ppxe ) ) == 0 ) ) { + DBGC ( pxe, "PXE %p has !PXE structure at " + "%04x:%04x\n", pxe, + pxe->ppxe.segment, pxe->ppxe.offset ); + pxe->entry = ppxe.EntryPointSP; + } + } + DBGC ( pxe, "PXE %p using entry point at %04x:%04x\n", pxe, + pxe->entry.segment, pxe->entry.offset ); + + /* Register PXE device */ + if ( undi_probe ( pxe ) == 0 ) { + /* Device registered; drop reference */ + pxe = NULL; + } else { + /* Not registered; re-use struct pxe_device */ + list_del ( &pxe->dev.siblings ); + } } - /* Allocate PXE device structure */ - pxe = malloc ( sizeof ( *pxe ) ); - if ( ! pxe ) { - rc = -ENOMEM; - goto err; - } - memset ( pxe, 0, sizeof ( *pxe ) ); - - /* Populate PXE device structure */ - pxe->pxenv.segment = pxenv_segment; - pxe->pxenv.offset = pxenv_offset; - INIT_LIST_HEAD ( &pxe->dev.children ); - pxe->dev.parent = &rootdev->dev; - if ( ( rc = pxedev_get_instance_info ( pxe ) ) != 0 ) - goto err; - - /* Register PXE device */ - if ( ( rc = register_pxedev ( pxe ) ) != 0 ) - goto err; - + free ( pxe ); return 0; err: @@ -299,7 +177,6 @@ static struct root_driver pxe_root_driver = { struct root_device pxe_root_device __root_device = { .name = "PXE", .driver = &pxe_root_driver, - .dev = { - .children = LIST_HEAD_INIT ( pxe_root_device.dev.children ), - }, }; + +#endif