view boot/config.c @ 21:e3accb15b1bb default tip

add alloc and loader.
author taiki
date Mon, 11 Feb 2013 04:30:42 +0900
parents 5e184d4c01b8
children
line wrap: on
line source

#include "bootx64.h"

#define FS_PRIVATE(n) (&(((fs_t *)n)->fs_priv.fs_data))

EFI_STATUS
open(fs_interface_t *this, EFI_FILE_HANDLE *fd, CHAR16 *name)
{
    fs_state_t *fs = FS_PRIVATE(this);
    EFI_STATUS status;

    if (name == NULL || fd == NULL) return EFI_INVALID_PARAMETER;

    status = uefi_call_wrapper(fs->volume->Open, 5, fs->volume, &fd, name, EFI_FILE_MODE_READ, (UINT64)0);

    return status;
}


EFI_STATUS
close(fs_interface_t *this, EFI_FILE_HANDLE *fd)
{
    fs_state_t *fs = FS_PRIVATE(this);
    if (fs == NULL || fd == NULL) return EFI_INVALID_PARAMETER;

    return uefi_call_wrapper(fs->volume->Close, 1, fd);
}

EFI_STATUS
read(fs_interface_t *this, EFI_FILE_HANDLE *fd, VOID *buf, UINTN *size)
{
    fs_state_t *fs = FS_PRIVATE(this);
    if (buf == NULL || fd == NULL || size == NULL) return EFI_INVALID_PARAMETER;
    return uefi_call_wrapper(fs->volume->Read, 3, fd, size, buf);
}

EFI_STATUS
seek(fs_interface_t *this, EFI_FILE_HANDLE *fd, UINTN newpos)
{
    fs_state_t *fs = FS_PRIVATE(this);
    if (newpos <= 0 || fd == NULL || fs == NULL) return EFI_INVALID_PARAMETER; 
    return uefi_call_wrapper(fs->volume->SetPosition, 2, *fd, newpos);
}



EFI_STATUS
config_fs_one(EFI_HANDLE dev, VOID *fs)
{
    EFI_STATUS status;
    EFI_FILE_IO_INTERFACE *volume;
    EFI_FILE_HANDLE volume_fh;
    EFI_GUID LocalFsProtocol = LOCALFS_PROTOCOL;

    status = uefi_call_wrapper(BS->HandleProtocol, 3, dev, &FileSystemProtocol, (VOID **)&volume);
    if (EFI_ERROR(status)) return EFI_INVALID_PARAMETER;

    /* alloc */

    status = uefi_call_wrapper(volume->OpenVolume, 2, volume, &volume_fh);
    if (EFI_ERROR(status)) {
        Print(L"Can not open volume.\n");
        return status;
    }
    Print(L"Open volume.\n");
    
    fs_state_t *fs_tmp = (fs_state_t *)fs;

    SetMem(fs, sizeof(fs_t), 0);

    fs_tmp->dev = dev;
    fs_tmp->volume = volume_fh;

    status = LibInstallProtocolInterfaces(&dev, &LocalFsProtocol, fs, NULL);
    if (EFI_ERROR(status)) return status; 
    /* free */

    return EFI_SUCCESS;
}



EFI_STATUS
config_fs(EFI_HANDLE boot_handle, fs_t *fs, dev_tab_t *boot_dev)
{
    Print(L"configure filesystems for all volume. \n");

    UINTN size = 0;
    EFI_STATUS status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, &FileSystemProtocol, NULL, &size, NULL);
    if (size == 0) return EFI_UNSUPPORTED;
    if (EFI_ERROR(status)) Print(L"efi unsupported. can not get handler.\n");

    size = 50 * sizeof(EFI_HANDLE);
    Print(L"find device, size=%d\n", size);

    dev_tab_t *dev_tab = NULL;

    /* alloc */
    if (EFI_SUCCESS != status) { 
        Print(L"can not allocate.\n");
        return status;
    }

    VOID *dev_tab = NULL;

    status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, &FileSystemProtocol, NULL, &size, (VOID **)dev_tab);
    if (EFI_NOT_FOUND == status) Print(L"EFI_NOT_FOUND\n");
    if (EFI_BUFFER_TOO_SMALL == status) Print(L"EFI_BUFFER_TOO_SMALL.\n");
    if (EFI_INVALID_PARAMETER == status) Print(L"EFI_INVALID_PARAMETER.\n");
    if (EFI_ERROR(status)) { 
        Print(L"can not get handler. status :%d\n", (int)status);
        return status;
    }
    
    UINTN ndev = size / sizeof(EFI_HANDLE);

    UINTN i;
    for (i = 0; i < ndev; i++) {
        VOID *fs = NULL;
        config_fs_one(dev_tab[i].dev, fs);
        //dev_tab[i].fs = fs;
    }

    EFI_GUID proto = LOCALFS_PROTOCOL;
    status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, proto, NULL, &size, NULL);
    if (EFI_ERROR(status)) {
        Print(L"No useable filesystem found.\n");
        return status;
    }
    
    SetMem(&proto, sizeof(EFI_HANDLE), 0);

    uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, &proto, NULL, &size, NULL);

    EFI_HANDLE *tab = NULL;

    SetMem(tab, size, 0);

    status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, proto, NULL, &size, tab);
    if (status != EFI_SUCCESS) {
        Print(L"faild to get handles\n");
    }

    size /= sizeof(EFI_HANDLE);

    UINTN idx = 0;

    for (i=0; i<size; i++) { 
        //dev_tab[idx].dev = tab[i];
        dev_tab[idx].dev = tab[i];
        // if (tab[i] == boot_handle) boot_dev = eh_tab + idx;
        idx++;
    }

    return EFI_SUCCESS;
}