176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ----------------------------------------------------------------------- *
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   This program is free software; you can redistribute it and/or modify
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   it under the terms of the GNU General Public License as published by
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   Boston MA 02111-1307, USA; either version 2 of the License, or
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   (at your option) any later version; incorporated herein by reference.
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ----------------------------------------------------------------------- */
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * memdisk.h
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Miscellaneous header definitions
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef MEMDISK_H
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MEMDISK_H
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stddef.h>
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* We use the com32 interface for calling 16-bit code */
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <com32.h>
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* define it only for i386 */
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if __SIZEOF_POINTER__ == 4
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __cdecl __attribute__((cdecl,regparm(0)))
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid __cdecl intcall(uint8_t, com32sys_t *, com32sys_t *);
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Structure passed in from the real-mode code */
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct real_mode_args {
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t rm_return;
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t rm_intcall;
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t rm_bounce;
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t rm_base;
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t rm_handle_interrupt;
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t rm_gdt;
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t rm_size;
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t rm_pmjmp;
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t rm_rmjmp;
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct real_mode_args rm_args;
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define sys_bounce ((void *)rm_args.rm_bounce)
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* This is the header in the boot sector/setup area */
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct setup_header {
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char cmdline[0x1f1];
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint8_t setup_secs;
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t syssize;
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t swap_dev;
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t ram_size;
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t vid_mode;
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t root_dev;
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t boot_flag;
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t jump;
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char header[4];
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t version;
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t realmode_swtch;
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t start_sys;
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint8_t type_of_loader;
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint8_t loadflags;
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t setup_move_size;
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t code32_start;
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t ramdisk_image;
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t ramdisk_size;
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t bootsect_kludge;
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t head_end_ptr;
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t pad1;
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t cmd_line_ptr;
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t initrd_addr_max;
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t esdi;
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t edx;
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t sssp;
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint32_t csip;
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define shdr ((struct setup_header *)rm_args.rm_base)
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Standard routines */
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid *memcpy(void *, const void *, size_t);
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid *memset(void *, int, size_t);
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid *memmove(void *, const void *, size_t);
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define strcpy(a,b)   __builtin_strcpy(a,b)
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline size_t strlen(const char *__a)
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const char *__D;
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    size_t __c;
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanasm("repne;scasb":"=D"(__D), "=c"(__c)
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman:	"D"(__a), "c"(-1), "a"(0), "m"(*__a));
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return __D - __a - 1;
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* memcpy() but returns a pointer to end of buffer */
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void *mempcpy(void *__d, const void *__s, unsigned int __n)
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memcpy(__d, __s, __n);
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return (void *)((char *)__d + __n);
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* memcmp() */
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline int memcmp(const void *__a, const void *__b, unsigned int __n)
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const unsigned char *__aa = __a;
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    const unsigned char *__bb = __b;
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    int __d;
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    while (__n--) {
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	__d = *__bb++ - *__aa++;
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (__d)
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    return __d;
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return 0;
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void sti(void)
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    asm volatile("sti");
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void cli(void)
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    asm volatile("cli");
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Decompression */
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int check_zip(void *indata, uint32_t size, uint32_t * zbytes_p,
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     uint32_t * dbytes_p, uint32_t * orig_crc,
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     uint32_t * offset_p);
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void *unzip(void *indata, uint32_t zbytes, uint32_t dbytes,
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		   uint32_t orig_crc, void *target);
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
141