/* libs/diskconfig/diskconfig.c
 *
 * Copyright 2008, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "config_mbr"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <cutils/log.h>

#include <diskconfig/diskconfig.h>


/* start and len are in LBA units */
static void
cfg_pentry(struct pc_partition *pentry, uint8_t status, uint8_t type,
           uint32_t start, uint32_t len)
{
    if (len > 0) {
        /* seems that somes BIOSens can get wedged on boot while verifying
         * the mbr if these are 0 */
        memset(&pentry->start, 0xff, sizeof(struct chs));
        memset(&pentry->end, 0xff, sizeof(struct chs));
    } else {
        /* zero out the c/h/s entries.. they are not used */
        memset(&pentry->start, 0, sizeof(struct chs));
        memset(&pentry->end, 0, sizeof(struct chs));
    }

    pentry->status = status;
    pentry->type = type;
    pentry->start_lba = start;
    pentry->len_lba = len;

    ALOGI("Configuring pentry. status=0x%x type=0x%x start_lba=%u len_lba=%u",
         pentry->status, pentry->type, pentry->start_lba, pentry->len_lba);
}


static inline uint32_t
kb_to_lba(uint32_t len_kb, uint32_t sect_size)
{
    uint64_t lba;

    lba = (uint64_t)len_kb * 1024;
    /* bump it up to the next LBA boundary just in case  */
    lba = (lba + (uint64_t)sect_size - 1) & ~((uint64_t)sect_size - 1);
    lba /= (uint64_t)sect_size;
    if (lba >= 0xffffffffULL)
        ALOGE("Error converting kb -> lba. 32bit overflow, expect weirdness");
    return (uint32_t)(lba & 0xffffffffULL);
}


static struct write_list *
mk_pri_pentry(struct disk_info *dinfo, struct part_info *pinfo, int pnum,
              uint32_t *lba)
{
    struct write_list *item;
    struct pc_partition *pentry;

    if (pnum >= PC_NUM_BOOT_RECORD_PARTS) {
        ALOGE("Maximum number of primary partition exceeded.");
        return NULL;
    }

    if (!(item = alloc_wl(sizeof(struct pc_partition)))) {
        ALOGE("Unable to allocate memory for partition entry.");
        return NULL;
    }

    {
        /* DO NOT DEREFERENCE */
        struct pc_boot_record *mbr = (void *)PC_MBR_DISK_OFFSET; 
        /* grab the offset in mbr where to write this partition entry. */
        item->offset = (loff_t)((uintptr_t)((uint8_t *)(&mbr->ptable[pnum])));
    }

    pentry = (struct pc_partition *) &item->data;

    /* need a standard primary partition entry */
    if (pinfo) {
        /* need this to be 64 bit in case len_kb is large */
        uint64_t len_lba; 

        if (pinfo->len_kb != (uint32_t)-1) {
            /* bump it up to the next LBA boundary just in case */
            len_lba = ((uint64_t)pinfo->len_kb * 1024);
            len_lba += ((uint64_t)dinfo->sect_size - 1);
            len_lba &= ~((uint64_t)dinfo->sect_size - 1);
            len_lba /= (uint64_t)dinfo->sect_size;
        } else {
            /* make it fill the rest of disk */
            len_lba = dinfo->num_lba - *lba;
        }

        cfg_pentry(pentry, ((pinfo->flags & PART_ACTIVE_FLAG) ?
                            PC_PART_ACTIVE : PC_PART_NORMAL),
                   pinfo->type, *lba, (uint32_t)len_lba);

        pinfo->start_lba = *lba;
        *lba += (uint32_t)len_lba;
    } else {
        /* this should be made an extended partition, and should take
         * up the rest of the disk as a primary partition */
        cfg_pentry(pentry, PC_PART_NORMAL, PC_PART_TYPE_EXTENDED,
                   *lba, dinfo->num_lba - *lba);

        /* note that we do not update the *lba because we now have to
         * create a chain of extended partition tables, and first one is at
         * *lba */
    }

    return item;
}


/* This function configures an extended boot record at the beginning of an
 * extended partition. This creates a logical partition and a pointer to
 * the next EBR.
 *
 * ext_lba == The start of the toplevel extended partition (pointed to by the
 * entry in the MBR).
 */
static struct write_list *
mk_ext_pentry(struct disk_info *dinfo, struct part_info *pinfo, uint32_t *lba,
              uint32_t ext_lba, struct part_info *pnext)
{
    struct write_list *item;
    struct pc_boot_record *ebr;
    uint32_t len; /* in lba units */

    if (!(item = alloc_wl(sizeof(struct pc_boot_record)))) {
        ALOGE("Unable to allocate memory for EBR.");
        return NULL;
    }

    /* we are going to write the ebr at the current LBA, and then bump the
     * lba counter since that is where the logical data partition will start */
    item->offset = ((loff_t)(*lba)) * dinfo->sect_size;
    (*lba)++;

    ebr = (struct pc_boot_record *) &item->data;
    memset(ebr, 0, sizeof(struct pc_boot_record));
    ebr->mbr_sig = PC_BIOS_BOOT_SIG;

    if (pinfo->len_kb != (uint32_t)-1)
        len = kb_to_lba(pinfo->len_kb, dinfo->sect_size);
    else {
        if (pnext) {
            ALOGE("Only the last partition can be specified to fill the disk "
                 "(name = '%s')", pinfo->name);
            goto fail;
        }
        len = dinfo->num_lba - *lba;
        /* update the pinfo structure to reflect the new size, for
         * bookkeeping */
        pinfo->len_kb =
            (uint32_t)(((uint64_t)len * (uint64_t)dinfo->sect_size) /
                       ((uint64_t)1024));
    }

    cfg_pentry(&ebr->ptable[PC_EBR_LOGICAL_PART], PC_PART_NORMAL,
               pinfo->type, 1, len);

    pinfo->start_lba = *lba;
    *lba += len;

    /* If this is not the last partition, we have to create a link to the
     * next extended partition.
     *
     * Otherwise, there's nothing to do since the "pointer entry" is
     * already zero-filled.
     */
    if (pnext) {
        /* The start lba for next partition is an offset from the beginning
         * of the top-level extended partition */
        uint32_t next_start_lba = *lba - ext_lba;
        uint32_t next_len_lba;
        if (pnext->len_kb != (uint32_t)-1)
            next_len_lba = 1 + kb_to_lba(pnext->len_kb, dinfo->sect_size);
        else
            next_len_lba = dinfo->num_lba - *lba;
        cfg_pentry(&ebr->ptable[PC_EBR_NEXT_PTR_PART], PC_PART_NORMAL,
                   PC_PART_TYPE_EXTENDED, next_start_lba, next_len_lba);
    }

    return item;

fail:
    free_wl(item);
    return NULL;
}


static struct write_list *
mk_mbr_sig()
{
    struct write_list *item;
    if (!(item = alloc_wl(sizeof(uint16_t)))) {
        ALOGE("Unable to allocate memory for MBR signature.");
        return NULL;
    }

    {
        /* DO NOT DEREFERENCE */
        struct pc_boot_record *mbr = (void *)PC_MBR_DISK_OFFSET;
        /* grab the offset in mbr where to write mbr signature. */
        item->offset = (loff_t)((uintptr_t)((uint8_t *)(&mbr->mbr_sig)));
    }

    *((uint16_t*)item->data) = PC_BIOS_BOOT_SIG;
    return item;
}

struct write_list *
config_mbr(struct disk_info *dinfo)
{
    struct part_info *pinfo;
    uint32_t cur_lba = dinfo->skip_lba;
    uint32_t ext_lba = 0;
    struct write_list *wr_list = NULL;
    struct write_list *temp_wr = NULL;
    int cnt = 0;
    int extended = 0;

    if (!dinfo->part_lst)
        return NULL;

    for (cnt = 0; cnt < dinfo->num_parts; ++cnt) {
        pinfo = &dinfo->part_lst[cnt];

        /* Should we create an extedned partition? */
        if (cnt == (PC_NUM_BOOT_RECORD_PARTS - 1)) {
            if (cnt + 1 < dinfo->num_parts) {
                extended = 1;
                ext_lba = cur_lba;
                if ((temp_wr = mk_pri_pentry(dinfo, NULL, cnt, &cur_lba)))
                    wlist_add(&wr_list, temp_wr);
                else {
                    ALOGE("Cannot create primary extended partition.");
                    goto fail;
                }
            }
        }

        /* if extended, need 1 lba for ebr */
        if ((cur_lba + extended) >= dinfo->num_lba)
            goto nospace;
        else if (pinfo->len_kb != (uint32_t)-1) {
            uint32_t sz_lba = (pinfo->len_kb / dinfo->sect_size) * 1024;
            if ((cur_lba + sz_lba + extended) > dinfo->num_lba)
                goto nospace;
        }

        if (!extended)
            temp_wr = mk_pri_pentry(dinfo, pinfo, cnt, &cur_lba);
        else {
            struct part_info *pnext;
            pnext = cnt + 1 < dinfo->num_parts ? &dinfo->part_lst[cnt+1] : NULL;
            temp_wr = mk_ext_pentry(dinfo, pinfo, &cur_lba, ext_lba, pnext);
        }

        if (temp_wr)
            wlist_add(&wr_list, temp_wr);
        else {
            ALOGE("Cannot create partition %d (%s).", cnt, pinfo->name);
            goto fail;
        }
    }

    /* fill in the rest of the MBR with empty parts (if needed). */
    for (; cnt < PC_NUM_BOOT_RECORD_PARTS; ++cnt) {
        struct part_info blank;
        cur_lba = 0;
        memset(&blank, 0, sizeof(struct part_info));
        if (!(temp_wr = mk_pri_pentry(dinfo, &blank, cnt, &cur_lba))) {
            ALOGE("Cannot create blank partition %d.", cnt);
            goto fail;
        }
        wlist_add(&wr_list, temp_wr);
    }

    if ((temp_wr = mk_mbr_sig()))
        wlist_add(&wr_list, temp_wr);
    else {
        ALOGE("Cannot set MBR signature");
        goto fail;
    }

    return wr_list;

nospace:
    ALOGE("Not enough space to add parttion '%s'.", pinfo->name);

fail:
    wlist_free(wr_list);
    return NULL;
}


/* Returns the device path of the partition referred to by 'name'
 * Must be freed by the caller.
 */
char *
find_mbr_part(struct disk_info *dinfo, const char *name)
{
    struct part_info *plist = dinfo->part_lst;
    int num = 0;
    char *dev_name = NULL;
    int has_extended = (dinfo->num_parts > PC_NUM_BOOT_RECORD_PARTS);

    for(num = 1; num <= dinfo->num_parts; ++num) {
        if (!strcmp(plist[num-1].name, name))
            break;
    }

    if (num > dinfo->num_parts)
        return NULL;

    if (has_extended && (num >= PC_NUM_BOOT_RECORD_PARTS))
        num++;

    if (!(dev_name = malloc(MAX_NAME_LEN))) {
        ALOGE("Cannot allocate memory.");
        return NULL;
    }

    num = snprintf(dev_name, MAX_NAME_LEN, "%s%d", dinfo->device, num);
    if (num >= MAX_NAME_LEN) {
        ALOGE("Device name is too long?!");
        free(dev_name);
        return NULL;
    }

    return dev_name;
}
