/*
 *   pc partition support
 *
 *   Copyright (C) 2004 Stefan Reinauer
 *
 *   This code is based (and copied in many places) from
 *   mac partition support by Samuel Rydh (samuel@ibrium.se)
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   version 2
 *
 */

#include "config.h"
#include "libopenbios/bindings.h"
#include "libopenbios/load.h"
#include "libc/byteorder.h"
#include "libc/vsprintf.h"
#include "packages.h"

//#define DEBUG_PC_PARTS

#ifdef DEBUG_PC_PARTS
#define DPRINTF(fmt, args...)                   \
    do { printk(fmt , ##args); } while (0)
#else
#define DPRINTF(fmt, args...)
#endif

typedef struct {
	xt_t		seek_xt, read_xt;
	ucell	        offs_hi, offs_lo;
        ucell	        size_hi, size_lo;
	phandle_t	filesystem_ph;
} pcparts_info_t;

DECLARE_NODE( pcparts, INSTALL_OPEN, sizeof(pcparts_info_t), "+/packages/pc-parts" );

#define SEEK( pos )		({ DPUSH(pos); call_parent(di->seek_xt); POP(); })
#define READ( buf, size )	({ PUSH(pointer2cell(buf)); PUSH(size); call_parent(di->read_xt); POP(); })

/* three helper functions */

static inline int has_pc_valid_partition(unsigned char *sect)
{
	/* Make sure the partition table contains at least one valid entry */
	return (sect[0x1c2] != 0 || sect[0x1d2] != 0 || sect[0x1e2] != 0);
}

static inline int has_pc_part_magic(unsigned char *sect)
{
	return sect[0x1fe]==0x55 && sect[0x1ff]==0xAA;
}

static inline int is_pc_extended_part(unsigned char type)
{
	return type==5 || type==0xf || type==0x85;
}

/* ( open -- flag ) */
static void
pcparts_open( pcparts_info_t *di )
{
	char *str = my_args_copy();
	char *argstr = strdup("");
	char *parstr = strdup("");
	int bs, parnum=-1;
	int found = 0;
	phandle_t ph;
	ducell offs, size;

	/* Layout of PC partition table */
	struct pc_partition {
		unsigned char boot;
		unsigned char head;
		unsigned char sector;
		unsigned char cyl;
		unsigned char type;
		unsigned char e_head;
		unsigned char e_sector;
		unsigned char e_cyl;
		u32 start_sect; /* unaligned little endian */
		u32 nr_sects; /* ditto */
	} *p, *partition;

	unsigned char buf[512];

	DPRINTF("pcparts_open '%s'\n", str );

	/* 
		Arguments that we accept:
		id: [0-7]
		[(id)][,][filespec]
	*/

	if ( strlen(str) ) {
		/* Detect the arguments */
		if ((*str >= '0' && *str <= '7') || (*str == ',')) {
		    push_str(str);
		    PUSH(',');
		    fword("left-parse-string");
		    parstr = pop_fstr_copy();
		    argstr = pop_fstr_copy();
		} else {
		    argstr = str;
		}
			
		/* Convert the id to a partition number */
		if (parstr && strlen(parstr))
		    parnum = atol(parstr);
	}

	/* Make sure argstr is not null */
	if (argstr == NULL)
	    argstr = strdup("");
	
	DPRINTF("parstr: %s  argstr: %s  parnum: %d\n", parstr, argstr, parnum);
        free(parstr);

	if( parnum < 0 )
		parnum = 0;

	di->filesystem_ph = 0;
	di->read_xt = find_parent_method("read");
	di->seek_xt = find_parent_method("seek");

	SEEK( 0 );
	if( READ(buf, 512) != 512 )
		RET(0);

	/* Check Magic */
	if (!has_pc_part_magic(buf)) {
		DPRINTF("pc partition magic not found.\n");
		RET(0);
	}

	/* Actual partition data */
	partition = (struct pc_partition *) (buf + 0x1be);

	/* Make sure we use a copy accessible from an aligned pointer (some archs
	   e.g. SPARC will crash otherwise) */
	p = malloc(sizeof(struct pc_partition));

	bs = 512;

	if (parnum < 4) {
		/* primary partition */
		partition += parnum;
		memcpy(p, partition, sizeof(struct pc_partition));

		if (p->type == 0 || is_pc_extended_part(p->type)) {
			DPRINTF("partition %d does not exist\n", parnum+1 );
			RET( 0 );
		}

		offs = (long long)(__le32_to_cpu(p->start_sect)) * bs;
		di->offs_hi = offs >> BITS;
		di->offs_lo = offs & (ucell) -1;

		size = (long long)(__le32_to_cpu(p->nr_sects)) * bs;
        	di->size_hi = size >> BITS;
        	di->size_lo = size & (ucell) -1;

		DPRINTF("Primary partition at sector %x\n", __le32_to_cpu(p->start_sect));

		/* If PReP boot partition, exit immediately with no filesystem probe */
		if (p->type == 0x41) {
			RET(-1);
		}

		found = 1;
	} else {
		/* Extended partition */
		int i, cur_part;
		unsigned long ext_start, cur_table;

		/* Search for the extended partition
		 * which contains logical partitions */
		for (i = 0; i < 4; i++) {
			if (is_pc_extended_part(p[i].type))
				break;
		}

		if (i >= 4) {
			DPRINTF("Extended partition not found\n");
			RET( 0 );
		}

		DPRINTF("Extended partition at %d\n", i+1);

		/* Visit each logical partition labels */
		ext_start = __le32_to_cpu(p[i].start_sect);
		cur_table = ext_start;
		cur_part = 4;

		while (cur_part <= parnum) {
			DPRINTF("cur_part=%d at %lx\n", cur_part, cur_table);

			SEEK( cur_table * bs );
			if( READ(buf, sizeof(512)) != sizeof(512) )
				RET( 0 );

			if (!has_pc_part_magic(buf)) {
				DPRINTF("Extended partition has no magic\n");
				break;
			}

			/* Read the extended partition, making sure we are aligned again */
			partition = (struct pc_partition *) (buf + 0x1be);
			memcpy(p, partition, sizeof(struct pc_partition));

			/* First entry is the logical partition */
			if (cur_part == parnum) {
				if (p->type == 0) {
					DPRINTF("Partition %d is empty\n", parnum+1);
					RET( 0 );
				}

				offs = (long long)(cur_table+__le32_to_cpu(p->start_sect)) * bs;
				di->offs_hi = offs >> BITS;
				di->offs_lo = offs & (ucell) -1;

				size = (long long)__le32_to_cpu(p->nr_sects) * bs;
				di->size_hi = size >> BITS;
				di->size_lo = size & (ucell) -1;

				/* If PReP boot partition, exit immediately with no filesystem probe */
				if (p->type == 0x41) {
					RET(-1);
				}

				found = 1;
				break;
			}

			/* Second entry is link to next partition */
			if (!is_pc_extended_part(p[1].type)) {
				DPRINTF("no link\n");
				break;
			}

			cur_table = ext_start + __le32_to_cpu(p[1].start_sect);
			cur_part++;
		}

		if (!found) {
			DPRINTF("Logical partition %d does not exist\n", parnum+1);
			RET( 0 );
		}
	}
	
	free(p);

	if (found) {
		/* We have a valid partition - so probe for a filesystem at the current offset */
		DPRINTF("pc-parts: about to probe for fs\n");
		DPUSH( offs );
		PUSH_ih( my_parent() );
		parword("find-filesystem");
		DPRINTF("pc-parts: done fs probe\n");
	
		ph = POP_ph();
		if( ph ) {
			DPRINTF("pc-parts: filesystem found with ph " FMT_ucellx " and args %s\n", ph, argstr);
			di->filesystem_ph = ph;

			/* If we have been asked to open a particular file, interpose the filesystem package with 
			the passed filename as an argument */
			if (strlen(argstr)) {
				push_str( argstr );
				PUSH_ph( ph );
				fword("interpose");
			}
		} else {
			DPRINTF("pc-parts: no filesystem found; bypassing misc-files interpose\n");
		}
	
		free( str );
		RET( -1 );
	} else {
		DPRINTF("pc-parts: unable to locate partition\n");

		free( str );
		RET( 0 );
	}
}

/* ( block0 -- flag? ) */
static void
pcparts_probe( pcparts_info_t *dummy )
{
	unsigned char *buf = (unsigned char *)cell2pointer(POP());

	DPRINTF("probing for PC partitions\n");

	/* We also check that at least one valid partition exists; this is because
	some CDs seem broken in that they have a partition table but it is empty
	e.g. MorphOS. */
	RET ( has_pc_part_magic(buf) && has_pc_valid_partition(buf) );
}

/* ( -- type offset.d size.d ) */
static void
pcparts_get_info( pcparts_info_t *di )
{
	DPRINTF("PC get_info\n");
	PUSH( -1 );		/* no type */
	PUSH( di->offs_lo );
	PUSH( di->offs_hi );
	PUSH( di->size_lo );
	PUSH( di->size_hi );
}

static void
pcparts_block_size( __attribute__((unused))pcparts_info_t *di )
{
	PUSH(512);
}

static void
pcparts_initialize( pcparts_info_t *di )
{
	fword("register-partition-package");
}

/* ( pos.d -- status ) */
static void
pcparts_seek(pcparts_info_t *di )
{
	long long pos = DPOP();
	long long offs, size;

	DPRINTF("pcparts_seek %llx:\n", pos);

	/* Seek is invalid if we reach the end of the device */
	size = ((ducell)di->size_hi << BITS) | di->size_lo;
	if (pos > size)
		RET( -1 );

	/* Calculate the seek offset for the parent */
	offs = ((ducell)di->offs_hi << BITS) | di->offs_lo;
	offs += pos;
	DPUSH(offs);

	DPRINTF("pcparts_seek parent offset %llx:\n", offs);

	call_package(di->seek_xt, my_parent());
}

/* ( buf len -- actlen ) */
static void
pcparts_read(pcparts_info_t *di )
{
	DPRINTF("pcparts_read\n");

	/* Pass the read back up to the parent */
	call_package(di->read_xt, my_parent());
}

/* ( addr -- size ) */
static void
pcparts_load( __attribute__((unused))pcparts_info_t *di )
{
	/* Invoke the loader */
	load(my_self());
}

/* ( pathstr len -- ) */
static void
pcparts_dir( pcparts_info_t *di )
{
	if ( di->filesystem_ph ) {
		PUSH( my_self() );
		push_str("dir");
		PUSH( di->filesystem_ph );
		fword("find-method");
		POP();
		fword("execute");
	} else {
		forth_printf("pc-parts: Unable to determine filesystem\n");
		POP();
		POP();
	}
}

NODE_METHODS( pcparts ) = {
	{ "probe",	pcparts_probe 		},
	{ "open",	pcparts_open 		},
	{ "seek",	pcparts_seek 		},
	{ "read",	pcparts_read 		},
	{ "load",	pcparts_load 		},
	{ "dir",	pcparts_dir 		},
	{ "get-info",	pcparts_get_info 	},
	{ "block-size",	pcparts_block_size 	},
	{ NULL,		pcparts_initialize	},
};

void
pcparts_init( void )
{
	REGISTER_NODE( pcparts );
}
