blob: e8126eccb4e8c6c5a9f266ea9431f9506485f4fc [file] [log] [blame] [edit]
/*
* Copyright (c) 2009 The Regents of the University of California
* See LICENSE for details.
*/
#ifndef ROS_INC_MPTABLES_H
#define ROS_INC_MPTABLES_H
#include <ros/common.h>
#include <pmap.h>
/*
* LICENCE NOTE: Most of these structures and some constants
* were blatently ripped out of BSD with <3. Only the camel
* casing has been changed to protect the innocent.
*/
// OBSCENELY IMPORTANT NOTE: None of this is packed. I didn't do it because BSD didnt. This may need to change
#define mptables_info(...) printk(__VA_ARGS__)
#define mptables_dump(...) //printk(__VA_ARGS__)
// The HEX representation of the ascii string _MP_ we search for
#define MP_SIG 0x5f504d5f /* _MP_ */
// Base and (inclusive bound) of the BIOS region to check
#define BIOS_ROM_BASE 0xf0000
#define BIOS_ROM_BOUND 0xffff0
// Where to look for the EBDA pointer
// Bound is dynamic. In first KB
#define EBDA_POINTER 0x040e
#define EBDA_SIZE 1024
/* BIOS: base memory size */
#define TOPOFMEM_POINTER 0x0413
#define IMCRP_MASK 0x80
// Sometimes the BIOS is a lying pain in my ass
// so don't believe it and assume this top of memory and check it
#define DEFAULT_TOPOFMEM 0xa0000
// How many entry types exist? Won't ever change
#define NUM_ENTRY_TYPES 5
#define INVALID_DEST_APIC 0xffff
#define MPFPS_SIZE 16 // For ivy
#define MPCTH_SIZE 44
// Sorry Zach, this has to be done.
#define READ_FROM_STORED_PHYSADDR32(addr) READ_FROM_STORED_VIRTADDR32(KADDR(addr))
#define READ_FROM_STORED_VIRTADDR32(addr) *((uint32_t* SAFE)addr)
enum interrupt_modes {
PIC, // PIC Mode
VW, // Virtural Wire Mode (Dev Boxes)
SIO // Once we fix up the ioapic, shift to this mode (not currently used)
};
// Start BSDs lovingly barrowed structs/etc
enum entry_types {
PROC = 0,
BUS = 1,
IOAPIC = 2,
INT = 3,
LINT = 4
};
enum bus_types {
CBUS = 1,
CBUSII = 2,
EISA = 3,
ISA = 6,
PCI = 13,
XPRESS = 18,
MAX_BUSTYPE = 18,
UNKNOWN_BUSTYPE = 0xff
};
typedef struct BUSTYPENAME {
uint8_t type;
char name[ 7 ];
} bus_type_name_t;
static bus_type_name_t bus_type_table[] =
{
{ CBUS, "CBUS" },
{ CBUSII, "CBUSII" },
{ EISA, "EISA" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" },
{ ISA, "ISA" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" },
{ PCI, "PCI" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" },
{ UNKNOWN_BUSTYPE, "---" }
};
typedef struct TABLE_ENTRY {
uint8_t type;
uint8_t length;
char name[ 32 ];
} table_entry_t;
static table_entry_t entry_types[] =
{
{ 0, 20, "Processor" },
{ 1, 8, "Bus" },
{ 2, 8, "I/O APIC" },
{ 3, 8, "I/O INT" },
{ 4, 8, "Local INT" }
};
/* MP Floating Pointer Structure */
typedef struct MPFPS {
char signature[ 4 ];
void* pap;
uint8_t length;
uint8_t spec_rev;
uint8_t checksum;
uint8_t mpfb1;
uint8_t mpfb2;
uint8_t mpfb3;
uint8_t mpfb4;
uint8_t mpfb5;
} mpfps_t;
/* MP Configuration Table Header */
typedef struct MPCTH {
char signature[ 4 ];
uint16_t base_table_length;
uint8_t spec_rev;
uint8_t checksum;
uint8_t oem_id[ 8 ];
uint8_t product_id[ 12 ];
void* oem_table_pointer;
uint16_t oem_table_size;
uint16_t entry_count;
void* apic_address;
uint16_t extended_table_length;
uint8_t extended_table_checksum;
uint8_t reserved;
} mpcth_t;
typedef struct PROCENTRY {
uint8_t type;
uint8_t apic_id;
uint8_t apic_version;
uint8_t cpu_flags;
uint32_t cpu_signature;
uint32_t feature_flags;
uint32_t reserved1;
uint32_t reserved2;
} proc_entry_t;
typedef struct BUSENTRY {
uint8_t type;
uint8_t bus_id;
char (NT bus_type)[ 6 ];
} bus_entry_t;
typedef struct IOAPICENTRY {
uint8_t type;
uint8_t apic_id;
uint8_t apic_version;
uint8_t apic_flags;
uintptr_t apic_address;
} ioapic_entry_t;
typedef struct INTENTRY {
uint8_t type;
uint8_t int_type;
uint16_t int_flags;
uint8_t src_bus_id;
uint8_t src_bus_irq;
uint8_t dst_apic_id;
uint8_t dst_apic_int;
} int_entry_t;
typedef struct PCIINTENTRY {
uint16_t dst_apic_id; // A value of INVALID_DEST_APIC means invalid (>=256)
uint8_t dst_apic_int;
} pci_int_entry_t;
typedef pci_int_entry_t isa_int_entry_t;
typedef struct PCIINTDEVICE {
pci_int_entry_t line[4];
} pci_int_device_t;
// Prototypes
void mptables_parse();
mpfps_t * COUNT(MPFPS_SIZE) find_floating_pointer(physaddr_t base, physaddr_t bound);
bool checksum(physaddr_t addr, uint32_t len);
void configuration_parse(physaddr_t conf_addr);
void proc_parse();
void bus_parse();
void ioapic_parse();
void int_parse();
void lint_parse();
#endif /* !ROS_INC_MPTABLES_H */