summaryrefslogtreecommitdiff
path: root/src/bios.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/bios.h')
-rw-r--r--src/bios.h580
1 files changed, 580 insertions, 0 deletions
diff --git a/src/bios.h b/src/bios.h
new file mode 100644
index 0000000..b420fff
--- /dev/null
+++ b/src/bios.h
@@ -0,0 +1,580 @@
+/*
+ * <bios.h>
+ *
+ * header for Open Hack'Ware
+ *
+ * Copyright (c) 2004-2005 Jocelyn Mayer
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License V2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#if !defined (__BIOS_H__)
+#define __BIOS_H__
+
+#define USE_OPENFIRMWARE
+//#define DEBUG_BIOS 1
+
+#define BIOS_VERSION "0.4.1"
+
+#define DSISR 18
+#define DAR 19
+#define SRR0 26
+#define SRR1 27
+
+#define _tostring(s) #s
+#define stringify(s) _tostring(s)
+
+#if !defined (ASSEMBLY_CODE)
+
+#ifdef DEBUG_BIOS
+#define DPRINTF(fmt, args...) do { dprintf(fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do { } while (0)
+#endif
+#define ERROR(fmt, args...) do { printf("ERROR: " fmt , ##args); } while (0)
+#define MSG(fmt, args...) do { printf(fmt , ##args); } while (0)
+
+#define offsetof(_struct, field) \
+({ \
+ typeof(_struct) __tmp_struct; \
+ int __off; \
+ __off = (char *)(&__tmp_struct.field) - (char *)(&__tmp_struct); \
+ __off; \
+})
+
+#define unused __attribute__ (( unused))
+
+/* Useful macro in C code */
+#define MTSPR(num, value) \
+__asm__ __volatile__ ("mtspr " stringify(num) ", %0" :: "r"(value));
+
+/* Architectures */
+enum {
+ ARCH_PREP = 0,
+ ARCH_CHRP,
+ ARCH_MAC99,
+ ARCH_POP,
+};
+
+/* Hardware definition(s) */
+extern uint32_t isa_io_base;
+#define ISA_IO_BASE 0x80000000
+extern int arch;
+
+/*****************************************************************************/
+/* From start.S : BIOS start code and asm helpers */
+void transfer_handler (void *residual, void *load_addr,
+ void *OF_entry, void *bootinfos,
+ void *cmdline, void *not_used,
+ void *nip, void *stack_base);
+void bug (void);
+
+/* PPC helpers */
+uint32_t mfmsr (void);
+void mtmsr (uint32_t msr);
+uint32_t mfpvr (void);
+void mftb (uint32_t *tb);
+void MMU_on (void);
+void MMU_off (void);
+/* IO helpers */
+uint32_t inb (uint16_t port);
+void outb (uint16_t port, uint32_t val);
+uint32_t inw (uint16_t port);
+void outw (uint16_t port, uint32_t val);
+uint32_t inl (uint16_t port);
+void outl (uint16_t port, uint32_t val);
+void eieio (void);
+/* Misc helpers */
+uint16_t ldswap16 (uint16_t *addr);
+void stswap16 (void *addr, uint16_t val);
+uint32_t ldswap32 (uint32_t *addr);
+void stswap32 (void *addr, uint32_t val);
+void mul64 (uint32_t *ret, uint32_t a, uint32_t b);
+void add64 (uint32_t *ret, uint32_t *a, uint32_t *b);
+
+typedef struct jmp_buf {
+ uint32_t gpr[32];
+ uint32_t lr;
+ uint32_t ctr;
+ uint32_t xer;
+ uint32_t ccr;
+} jmp_buf;
+int setjmp (jmp_buf env);
+void longjmp (jmp_buf env);
+
+/*****************************************************************************/
+/* PCI BIOS */
+typedef struct pci_common_t pci_common_t;
+typedef struct pci_host_t pci_host_t;
+typedef struct pci_device_t pci_device_t;
+typedef struct pci_bridge_t pci_bridge_t;
+typedef struct pci_ops_t pci_ops_t;
+typedef union pci_u_t pci_u_t;
+
+typedef struct pci_dev_t pci_dev_t;
+struct pci_dev_t {
+ uint16_t vendor;
+ uint16_t product;
+ const unsigned char *type;
+ const unsigned char *name;
+ const unsigned char *model;
+ const unsigned char *compat;
+ int acells;
+ int scells;
+ int icells;
+ int (*config_cb)(pci_device_t *device);
+ const void *private;
+};
+
+pci_host_t *pci_init (void);
+void pci_get_mem_range (pci_host_t *host, uint32_t *start, uint32_t *len);
+
+/*****************************************************************************/
+/* nvram.c : NVRAM management routines */
+typedef struct nvram_t nvram_t;
+extern nvram_t *nvram;
+
+uint8_t NVRAM_read (nvram_t *nvram, uint32_t addr);
+void NVRAM_write (nvram_t *nvram, uint32_t addr, uint8_t value);
+uint16_t NVRAM_get_size (nvram_t *nvram);
+int NVRAM_format (nvram_t *nvram);
+nvram_t *NVRAM_get_config (uint32_t *RAM_size, int *boot_device,
+ void **boot_image, uint32_t *boot_size,
+ void **cmdline, uint32_t *cmdline_size,
+ void **ramdisk, uint32_t *ramdisk_size);
+
+/*****************************************************************************/
+/* bloc.c : bloc devices management */
+typedef struct pos_t {
+ uint32_t bloc;
+ uint32_t offset;
+} pos_t;
+
+typedef struct bloc_device_t bloc_device_t;
+typedef struct part_t part_t;
+typedef struct fs_t fs_t;
+
+bloc_device_t *bd_open (int device);
+int bd_seek (bloc_device_t *bd, uint32_t bloc, uint32_t pos);
+int bd_read (bloc_device_t *bd, void *buffer, int len);
+int bd_write (bloc_device_t *bd, const void *buffer, int len);
+#define _IOCTL(a, b) (((a) << 16) | (b))
+#define MEM_SET_ADDR _IOCTL('M', 0x00)
+#define MEM_SET_SIZE _IOCTL('M', 0x01)
+int bd_ioctl (bloc_device_t *bd, int func, void *args);
+uint32_t bd_seclen (bloc_device_t *bd);
+void bd_close (bloc_device_t *bd);
+uint32_t bd_seclen (bloc_device_t *bd);
+uint32_t bd_maxbloc (bloc_device_t *bd);
+void bd_sect2CHS (bloc_device_t *bd, uint32_t secnum,
+ int *cyl, int *head, int *sect);
+uint32_t bd_CHS2sect (bloc_device_t *bd,
+ int cyl, int head, int sect);
+part_t *bd_probe (int boot_device);
+bloc_device_t *bd_get (int device);
+void bd_put (bloc_device_t *bd);
+void bd_set_boot_part (bloc_device_t *bd, part_t *partition);
+part_t **_bd_parts (bloc_device_t *bd);
+
+void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1,
+ uint32_t io_base2, uint32_t io_base3,
+ void *OF_private);
+void ide_pci_pmac_register (uint32_t io_base0, uint32_t io_base1,
+ void *OF_private);
+
+/*****************************************************************************/
+/* part.c : partitions management */
+enum part_flags_t {
+ PART_TYPE_RAW = 0x0000,
+ PART_TYPE_PREP = 0x0001,
+ PART_TYPE_APPLE = 0x0002,
+ PART_TYPE_ISO9660 = 0x0004,
+ PART_FLAG_DUMMY = 0x0010,
+ PART_FLAG_DRIVER = 0x0020,
+ PART_FLAG_PATCH = 0x0040,
+ PART_FLAG_FS = 0x0080,
+ PART_FLAG_BOOT = 0x0100,
+};
+
+enum {
+ PART_PREP = 0x01,
+ PART_CHRP = 0x02,
+};
+
+part_t *part_open (bloc_device_t *bd,
+ uint32_t start, uint32_t size, uint32_t spb);
+int part_seek (part_t *part, uint32_t bloc, uint32_t pos);
+int part_read (part_t *part, void *buffer, int len);
+int part_write (part_t *part, const void *buffer, int len);
+void part_close (part_t *part);
+uint32_t part_blocsize (part_t *part);
+uint32_t part_flags (part_t *part);
+uint32_t part_size (part_t *part);
+fs_t *part_fs (part_t *part);
+
+part_t *part_get (bloc_device_t *bd, int partnum);
+part_t *part_probe (bloc_device_t *bd, int set_raw);
+int part_set_boot_file (part_t *part, uint32_t start, uint32_t offset,
+ uint32_t size);
+
+/*****************************************************************************/
+/* fs.c : file system management */
+typedef struct dir_t dir_t;
+typedef struct dirent_t dirent_t;
+typedef struct inode_t inode_t;
+
+struct dirent_t {
+ dir_t *dir;
+ inode_t *inode;
+ const unsigned char *dname;
+};
+
+enum {
+ INODE_TYPE_UNKNOWN = 0x00FF,
+ INODE_TYPE_DIR = 0x0000,
+ INODE_TYPE_FILE = 0x0001,
+ INODE_TYPE_OTHER = 0x0002,
+ INODE_TYPE_MASK = 0x00FF,
+ INODE_FLAG_EXEC = 0x0100,
+ INODE_FLAG_BOOT = 0x0200,
+ INODE_FLAG_MASK = 0xFF00,
+};
+
+/* probe a filesystem from a partition */
+fs_t *fs_probe (part_t *part, int set_raw);
+part_t *fs_part (fs_t *fs);
+/* Recurse thru directories */
+dir_t *fs_opendir (fs_t *fs, const unsigned char *name);
+dirent_t *fs_readdir (dir_t *dir);
+unsigned char *fs_get_path (dirent_t *dirent);
+void fs_closedir (dir_t *dir);
+/* Play with files */
+inode_t *fs_open (fs_t *fs, const unsigned char *name);
+int fs_seek (inode_t *inode, uint32_t bloc, uint32_t pos);
+int fs_read (inode_t *inode, void *buffer, int len);
+int fs_write (inode_t *inode, const void *buffer, unused int len);
+void fs_close (inode_t *inode);
+uint32_t fs_get_type (fs_t *fs);
+uint32_t fs_inode_get_type (inode_t *inode);
+uint32_t fs_inode_get_flags (inode_t *inode);
+part_t *fs_inode_get_part (inode_t *inode);
+
+/* Bootfile */
+unsigned char *fs_get_boot_dirname (fs_t *fs);
+inode_t *fs_get_bootfile (fs_t *fs);
+int fs_raw_set_bootfile (part_t *part,
+ uint32_t start_bloc, uint32_t start_offset,
+ uint32_t size_bloc, uint32_t size_offset);
+
+/*****************************************************************************/
+/* file.c : file management */
+#define DEFAULT_LOAD_DEST 0x00100000
+
+uint32_t file_seek (inode_t *file, uint32_t pos);
+
+/* Executable files loader */
+int bootfile_load (void **dest, void **entry, void **end,
+ part_t *part, int type, const unsigned char *fname,
+ uint32_t offset);
+
+/*****************************************************************************/
+/* char.c : char devices */
+typedef struct chardev_t chardev_t;
+typedef struct cops_t cops_t;
+
+struct cops_t {
+ int (*open)(void *private);
+ int (*close)(void *private);
+ int (*read)(void *private);
+ int (*write)(void *private, int c);
+ /* Won't implement seek for now */
+};
+
+enum {
+ CHARDEV_KBD = 0,
+ CHARDEV_MOUSE,
+ CHARDEV_SERIAL,
+ CHARDEV_DISPLAY,
+ CHARDEV_LAST,
+};
+
+int chardev_register (int type, cops_t *ops, void *private);
+int chardev_open (chardev_t *dev);
+int chardev_close (chardev_t *dev);
+int chardev_read (chardev_t *dev, void *buffer, int maxlen);
+int chardev_write (chardev_t *dev, const void *buffer, int maxlen);
+int chardev_type (chardev_t *dev);
+
+/* Console driver */
+int console_open (void);
+int console_read (void *buffer, int maxlen);
+int console_write (const void *buffer, int len);
+void console_close (void);
+
+/* PC serial port */
+#define SERIAL_OUT_PORT (0x03F8)
+int pc_serial_register (uint16_t base);
+
+/* CUDA host */
+typedef struct cuda_t cuda_t;
+cuda_t *cuda_init (uint32_t base);
+void cuda_reset (cuda_t *cuda);
+
+/*****************************************************************************/
+/* vga.c : VGA console */
+extern unsigned long vga_fb_phys_addr;
+extern int vga_fb_width;
+extern int vga_fb_height;
+extern int vga_fb_linesize;
+extern int vga_fb_bpp;
+extern int vga_fb_depth;
+void vga_prep_init(void);
+void vga_set_address (uint32_t address);
+void vga_set_mode(int width, int height, int depth);
+void vga_set_palette(int i, unsigned int rgba);
+#define RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+#define RGB(r, g, b) RGBA(r, g, b, 0xff)
+unsigned int vga_get_color(unsigned int rgba);
+
+void vga_draw_buf (const void *buf, int buf_linesize,
+ int posx, int posy, int width, int height);
+void vga_fill_rect (int posx, int posy, int width, int height, uint32_t color);
+void vga_bitblt(int xs, int ys, int xd, int yd, int w, int h);
+void vga_check_mode(int width, int height, int depth);
+
+/* text primitives */
+void vga_text_set_fgcol(unsigned int rgba);
+void vga_text_set_bgcol(unsigned int rgba);
+void vga_putcharxy(int x, int y, int ch,
+ unsigned int fgcol, unsigned int bgcol);
+void vga_putchar(int ch);
+void vga_puts(const char *s);
+
+/*****************************************************************************/
+/* bootinfos.c : build structures needed by kernels to boot */
+void prepare_bootinfos (void *p, uint32_t memsize,
+ void *cmdline, void *initrd, uint32_t initrd_size);
+void residual_build (void *p, uint32_t memsize,
+ uint32_t load_base, uint32_t load_size,
+ uint32_t last_alloc);
+
+/*****************************************************************************/
+/* of.c : Open-firmware emulation */
+#define OF_NAMELEN_MAX 1024
+#define OF_PROPLEN_MAX 256
+
+int OF_init (void);
+int OF_register_mb (const unsigned char *model, const unsigned char **compats);
+int OF_register_cpu (const unsigned char *name, int num, uint32_t pvr,
+ uint32_t min_freq, uint32_t max_freq, uint32_t bus_freq,
+ uint32_t tb_freq, uint32_t reset_io);
+#if 0
+int OF_register_translations (int nb, OF_transl_t *translations);
+#endif
+uint32_t OF_claim_virt (uint32_t virt, uint32_t size, int *range);
+int OF_register_memory (uint32_t memsize, uint32_t bios_size);
+int OF_register_bootargs (const unsigned char *bootargs);
+void *OF_register_pci_host (pci_dev_t *dev, uint16_t rev, uint32_t ccode,
+ uint32_t cfg_base, uint32_t cfg_len,
+ uint32_t mem_base, uint32_t mem_len,
+ uint32_t io_base, uint32_t io_len,
+ uint32_t rbase, uint32_t rlen,
+ uint16_t min_grant, uint16_t max_latency);
+void *OF_register_pci_bridge (void *parent, pci_dev_t *dev,
+ uint32_t cfg_base, uint32_t cfg_len,
+ uint8_t devfn, uint8_t rev, uint32_t ccode,
+ uint16_t min_grant, uint16_t max_latency);
+void *OF_register_pci_device (void *parent, pci_dev_t *dev,
+ uint8_t devfn, uint8_t rev, uint32_t ccode,
+ uint16_t min_grant, uint16_t max_latency);
+void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses);
+void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
+ uint32_t *regions, uint32_t *sizes);
+void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
+ void *private_data);
+int OF_register_bus (const unsigned char *name, uint32_t address,
+ const unsigned char *type);
+int OF_register_serial (const unsigned char *bus, const unsigned char *name,
+ uint32_t io_base, int irq);
+int OF_register_stdio (const unsigned char *dev_in,
+ const unsigned char *dev_out);
+void OF_vga_register (const unsigned char *name, uint32_t address,
+ int width, int height, int depth);
+void *OF_blockdev_register (void *parent, void *private,
+ const unsigned char *type,
+ const unsigned char *name, int devnum,
+ const char *alias);
+void OF_blockdev_set_boot_device (void *disk, int partnum,
+ const unsigned char *file);
+
+int OF_entry (void *p);
+int OF_client_entry (void *p);
+void RTAS_init (void);
+
+/*****************************************************************************/
+/* main.c : main BIOS code */
+/* Memory management */
+/* Memory areas */
+extern uint32_t _data_start, _data_end;
+extern uint32_t _OF_vars_start, _OF_vars_end;
+extern uint32_t _sdata_start, _sdata_end;
+extern uint32_t _ro_start, _ro_end;
+extern uint32_t _RTAS_start, _RTAS_end;
+extern uint32_t _RTAS_data_start, _RTAS_data_end;
+extern uint32_t _bss_start, _bss_end;
+extern uint32_t _ram_start;
+extern const unsigned char *BIOS_str;
+extern const unsigned char *copyright;
+void *mem_align (int align);
+void freep (void *p);
+
+/* Endian-safe memory read/write */
+static inline void put_be64 (void *addr, uint64_t l)
+{
+ *(uint64_t *)addr = l;
+}
+
+static inline uint64_t get_be64 (void *addr)
+{
+ return *(uint64_t *)addr;
+}
+
+static inline void put_le64 (void *addr, uint64_t l)
+{
+ uint32_t *p;
+
+ p = addr;
+ stswap32(p, l);
+ stswap32(p + 1, l >> 32);
+}
+
+static inline uint64_t get_le64 (void *addr)
+{
+ uint64_t val;
+ uint32_t *p;
+
+ p = addr;
+ val = ldswap32(p);
+ val |= (uint64_t)ldswap32(p + 1) << 32;
+
+ return val;
+}
+
+static inline void put_be32 (void *addr, uint32_t l)
+{
+ *(uint32_t *)addr = l;
+}
+
+static inline uint32_t get_be32 (void *addr)
+{
+ return *(uint32_t *)addr;
+}
+
+static inline void put_le32 (void *addr, uint32_t l)
+{
+ stswap32(addr, l);
+}
+
+static inline uint32_t get_le32 (void *addr)
+{
+ return ldswap32(addr);
+}
+
+static inline void put_be16 (void *addr, uint16_t l)
+{
+ *(uint16_t *)addr = l;
+}
+
+static inline uint16_t get_be16 (void *addr)
+{
+ return *(uint16_t *)addr;
+}
+
+static inline void put_le16 (void *addr, uint16_t l)
+{
+ stswap16(addr, l);
+}
+
+static inline uint16_t get_le16 (void *addr)
+{
+ return ldswap16(addr);
+}
+
+/* String functions */
+long strtol (const unsigned char *str, unsigned char **end, int base);
+
+int write_buf (const unsigned char *buf, int len);
+
+/* Misc */
+void usleep (uint32_t usec);
+void sleep (int sec);
+uint32_t crc32 (uint32_t crc, const uint8_t *p, int len);
+void set_loadinfo (void *load_base, uint32_t size);
+void set_check (int do_it);
+void check_location (const void *buf, const char *func, const char *name);
+
+static inline void pokeb (void *location, uint8_t val)
+{
+#ifdef DEBUG_BIOS
+ check_location(location, __func__, "location");
+#endif
+ *((uint8_t *)location) = val;
+}
+
+static inline uint8_t peekb (void *location)
+{
+#ifdef DEBUG_BIOS
+ check_location(location, __func__, "location");
+#endif
+ return *((uint8_t *)location);
+}
+
+static inline void pokew (void *location, uint16_t val)
+{
+#ifdef DEBUG_BIOS
+ check_location(location, __func__, "location");
+#endif
+ *((uint8_t *)location) = val;
+}
+
+static inline uint16_t peekw (void *location)
+{
+#ifdef DEBUG_BIOS
+ check_location(location, __func__, "location");
+#endif
+ return *((uint16_t *)location);
+}
+
+static inline void pokel (void *location, uint32_t val)
+{
+#ifdef DEBUG_BIOS
+ check_location(location, __func__, "location");
+#endif
+ *((uint32_t *)location) = val;
+}
+
+static inline uint32_t peekl (void *location)
+{
+#ifdef DEBUG_BIOS
+ check_location(location, __func__, "location");
+#endif
+ return *((uint32_t *)location);
+}
+
+/* Console */
+int cs_write (const unsigned char *buf, int len);
+
+#endif /* !defined (ASSEMBLY_CODE) */
+
+
+#endif /* !defined (__BIOS_H__) */