提交 9d24b01c 编写于 作者: T Tom Rini
......@@ -12,12 +12,13 @@
DECLARE_GLOBAL_DATA_PTR;
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *entries)
{
unsigned num_entries;
unsigned int num_entries;
int i;
num_entries = min((unsigned)lib_sysinfo.n_memranges, max_entries);
num_entries = min((unsigned int)lib_sysinfo.n_memranges, max_entries);
if (num_entries < lib_sysinfo.n_memranges) {
printf("Warning: Limiting e820 map to %d entries.\n",
num_entries);
......
......@@ -9,7 +9,8 @@
DECLARE_GLOBAL_DATA_PTR;
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *entries)
{
entries[0].addr = 0;
entries[0].size = ISA_START_ADDRESS;
......
......@@ -99,7 +99,8 @@ static struct sfi_table_simple *sfi_search_mmap(void)
i < SFI_GET_NUM_ENTRIES(sb, struct sfi_mem_entry); \
i++, mentry++) \
static unsigned sfi_setup_e820(unsigned max_entries, struct e820entry *entries)
static unsigned int sfi_setup_e820(unsigned int max_entries,
struct e820_entry *entries)
{
struct sfi_table_simple *sb;
struct sfi_mem_entry *mentry;
......@@ -188,7 +189,8 @@ static phys_size_t sfi_get_ram_size(void)
return ram;
}
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *entries)
{
return sfi_setup_e820(max_entries, entries);
}
......
......@@ -111,7 +111,7 @@ struct boot_params {
struct setup_header hdr; /* setup header */ /* 0x1f1 */
__u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */
struct e820entry e820_map[E820MAX]; /* 0x2d0 */
struct e820_entry e820_map[E820MAX]; /* 0x2d0 */
__u8 _pad8[48]; /* 0xcd0 */
struct edd_info eddbuf[EDDMAXNR]; /* 0xd00 */
__u8 _pad9[276]; /* 0xeec */
......
......@@ -12,7 +12,7 @@
#ifndef __ASSEMBLY__
#include <linux/types.h>
struct e820entry {
struct e820_entry {
__u64 addr; /* start of memory segment */
__u64 size; /* size of memory segment */
__u32 type; /* type of memory segment */
......@@ -24,6 +24,7 @@ struct e820entry {
#endif /* __ASSEMBLY__ */
/* Implementation defined function to install an e820 map */
unsigned install_e820_map(unsigned max_entries, struct e820entry *);
unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *);
#endif /* _ASM_X86_E820_H */
......@@ -61,49 +61,53 @@
#define readb(addr) (*(volatile unsigned char *) (addr))
#define readw(addr) (*(volatile unsigned short *) (addr))
#define readl(addr) (*(volatile unsigned int *) (addr))
#define readq(addr) (*(volatile unsigned long long *) (addr))
#define __raw_readb readb
#define __raw_readw readw
#define __raw_readl readl
#define __raw_readq readq
#define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b))
#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b))
#define writel(b,addr) (*(volatile unsigned int *) (addr) = (b))
#define writeq(b,addr) (*(volatile unsigned long long *) (addr) = (b))
#define __raw_writeb writeb
#define __raw_writew writew
#define __raw_writel writel
#define __raw_writeq writeq
#define memset_io(a,b,c) memset((a),(b),(c))
#define memcpy_fromio(a,b,c) memcpy((a),(b),(c))
#define memcpy_toio(a,b,c) memcpy((a),(b),(c))
#define write_arch(type, endian, a, v) __raw_write##type(cpu_to_##endian(v), a)
#define read_arch(type, endian, a) endian##_to_cpu(__raw_read##type(a))
#define out_arch(type, endian, a, v) __raw_write##type(cpu_to_##endian(v), a)
#define in_arch(type, endian, a) endian##_to_cpu(__raw_read##type(a))
#define write_le64(a, v) write_arch(q, le64, a, v)
#define write_le32(a, v) write_arch(l, le32, a, v)
#define write_le16(a, v) write_arch(w, le16, a, v)
#define out_le64(a, v) out_arch(q, le64, a, v)
#define out_le32(a, v) out_arch(l, le32, a, v)
#define out_le16(a, v) out_arch(w, le16, a, v)
#define read_le64(a) read_arch(q, le64, a)
#define read_le32(a) read_arch(l, le32, a)
#define read_le16(a) read_arch(w, le16, a)
#define in_le64(a) in_arch(q, le64, a)
#define in_le32(a) in_arch(l, le32, a)
#define in_le16(a) in_arch(w, le16, a)
#define write_be32(a, v) write_arch(l, be32, a, v)
#define write_be16(a, v) write_arch(w, be16, a, v)
#define out_be32(a, v) out_arch(l, be32, a, v)
#define out_be16(a, v) out_arch(w, be16, a, v)
#define read_be32(a) read_arch(l, be32, a)
#define read_be16(a) read_arch(w, be16, a)
#define in_be32(a) in_arch(l, be32, a)
#define in_be16(a) in_arch(w, be16, a)
#define write_8(a, v) __raw_writeb(v, a)
#define read_8(a) __raw_readb(a)
#define out_8(a, v) __raw_writeb(v, a)
#define in_8(a) __raw_readb(a)
#define clrbits(type, addr, clear) \
write_##type((addr), read_##type(addr) & ~(clear))
out_##type((addr), in_##type(addr) & ~(clear))
#define setbits(type, addr, set) \
write_##type((addr), read_##type(addr) | (set))
out_##type((addr), in_##type(addr) | (set))
#define clrsetbits(type, addr, clear, set) \
write_##type((addr), (read_##type(addr) & ~(clear)) | (set))
out_##type((addr), (in_##type(addr) & ~(clear)) | (set))
#define clrbits_be32(addr, clear) clrbits(be32, addr, clear)
#define setbits_be32(addr, set) setbits(be32, addr, set)
......
......@@ -185,6 +185,7 @@ static void setup_realmode_idt(void)
write_idt_stub((void *)0xffe6e, 0x1a);
}
#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
static u8 vbe_get_mode_info(struct vbe_mode_info *mi)
{
u16 buffer_seg;
......@@ -241,6 +242,7 @@ static void vbe_set_graphics(int vesa_mode, struct vbe_mode_info *mode_info)
mode_info->video_mode &= 0x3ff;
vbe_set_mode(mode_info);
}
#endif /* CONFIG_FRAMEBUFFER_SET_VESA_MODE */
void bios_run_on_x86(struct udevice *dev, unsigned long addr, int vesa_mode,
struct vbe_mode_info *mode_info)
......@@ -273,8 +275,10 @@ void bios_run_on_x86(struct udevice *dev, unsigned long addr, int vesa_mode,
0x0);
debug("done\n");
#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
if (vesa_mode != -1)
vbe_set_graphics(vesa_mode, mode_info);
#endif
}
asmlinkage int interrupt_handler(u32 intnumber, u32 gsfs, u32 dses,
......
......@@ -100,7 +100,7 @@ void write_coreboot_table(u32 addr, struct memory_area *cfg_tables)
struct cb_record *cbr;
struct cb_memory *mem;
struct cb_memory_range *map;
struct e820entry e820[32];
struct e820_entry e820[32];
struct cb_framebuffer *fb;
struct vesa_mode_info *vesa;
int i, num;
......
......@@ -17,8 +17,8 @@ DECLARE_GLOBAL_DATA_PTR;
* 0x100000-gd->ram_size Useable RAM
* CONFIG_PCIE_ECAM_BASE PCIe ECAM
*/
__weak unsigned install_e820_map(unsigned max_entries,
struct e820entry *entries)
__weak unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *entries)
{
entries[0].addr = 0;
entries[0].size = ISA_START_ADDRESS;
......
......@@ -62,9 +62,10 @@ ulong board_get_usable_ram_top(ulong total_size)
return fsp_get_usable_lowmem_top(gd->arch.hob_list);
}
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *entries)
{
unsigned num_entries = 0;
unsigned int num_entries = 0;
const struct hob_header *hdr;
struct hob_res_desc *res_desc;
......
......@@ -3,4 +3,4 @@ M: Simon Glass <sjg@chromium.org>
S: Maintained
F: board/coreboot/coreboot/
F: include/configs/chromebook_link.h
F: configs/coreboot-x86_defconfig
F: configs/coreboot_defconfig
......@@ -20,13 +20,52 @@
#include <net.h>
#include <vxworks.h>
#ifdef CONFIG_X86
#include <vbe.h>
#include <asm/e820.h>
#include <linux/linkage.h>
#endif
/*
* A very simple elf loader, assumes the image is valid, returns the
* A very simple ELF64 loader, assumes the image is valid, returns the
* entry point address.
*
* Note if U-Boot is 32-bit, the loader assumes the to segment's
* physical address and size is within the lower 32-bit address space.
*/
static unsigned long load_elf64_image_phdr(unsigned long addr)
{
Elf64_Ehdr *ehdr; /* Elf header structure pointer */
Elf64_Phdr *phdr; /* Program header structure pointer */
int i;
ehdr = (Elf64_Ehdr *)addr;
phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
/* Load each program header */
for (i = 0; i < ehdr->e_phnum; ++i) {
void *dst = (void *)(ulong)phdr->p_paddr;
void *src = (void *)addr + phdr->p_offset;
debug("Loading phdr %i to 0x%p (%lu bytes)\n",
i, dst, (ulong)phdr->p_filesz);
if (phdr->p_filesz)
memcpy(dst, src, phdr->p_filesz);
if (phdr->p_filesz != phdr->p_memsz)
memset(dst + phdr->p_filesz, 0x00,
phdr->p_memsz - phdr->p_filesz);
flush_cache((unsigned long)dst, phdr->p_filesz);
++phdr;
}
return ehdr->e_entry;
}
/*
* A very simple ELF loader, assumes the image is valid, returns the
* entry point address.
*
* The loader firstly reads the EFI class to see if it's a 64-bit image.
* If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
*/
static unsigned long load_elf_image_phdr(unsigned long addr)
{
......@@ -35,12 +74,16 @@ static unsigned long load_elf_image_phdr(unsigned long addr)
int i;
ehdr = (Elf32_Ehdr *)addr;
if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
return load_elf64_image_phdr(addr);
phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
/* Load each program header */
for (i = 0; i < ehdr->e_phnum; ++i) {
void *dst = (void *)(uintptr_t)phdr->p_paddr;
void *src = (void *)addr + phdr->p_offset;
debug("Loading phdr %i to 0x%p (%i bytes)\n",
i, dst, phdr->p_filesz);
if (phdr->p_filesz)
......@@ -203,14 +246,17 @@ int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned long addr; /* Address of image */
unsigned long bootaddr; /* Address to put the bootline */
unsigned long bootaddr = 0; /* Address to put the bootline */
char *bootline; /* Text of the bootline */
char *tmp; /* Temporary char pointer */
char build_buf[128]; /* Buffer for building the bootline */
int ptr = 0;
#ifdef CONFIG_X86
struct e820info *info;
struct e820entry *data;
ulong base;
struct e820_info *info;
struct e820_entry *data;
struct efi_gop_info *gop;
struct vesa_mode_info *vesa = &mode_info.vesa;
#endif
/*
......@@ -249,6 +295,45 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
puts("## Ethernet MAC address not copied to NV RAM\n");
#endif
#ifdef CONFIG_X86
/*
* Get VxWorks's physical memory base address from environment,
* if we don't specify it in the environment, use a default one.
*/
base = env_get_hex("vx_phys_mem_base", VXWORKS_PHYS_MEM_BASE);
data = (struct e820_entry *)(base + E820_DATA_OFFSET);
info = (struct e820_info *)(base + E820_INFO_OFFSET);
memset(info, 0, sizeof(struct e820_info));
info->sign = E820_SIGNATURE;
info->entries = install_e820_map(E820MAX, data);
info->addr = (info->entries - 1) * sizeof(struct e820_entry) +
E820_DATA_OFFSET;
/*
* Explicitly clear the bootloader image size otherwise if memory
* at this offset happens to contain some garbage data, the final
* available memory size for the kernel is insane.
*/
*(u32 *)(base + BOOT_IMAGE_SIZE_OFFSET) = 0;
/*
* Prepare compatible framebuffer information block.
* The VESA mode has to be 32-bit RGBA.
*/
if (vesa->x_resolution && vesa->y_resolution) {
gop = (struct efi_gop_info *)(base + EFI_GOP_INFO_OFFSET);
gop->magic = EFI_GOP_INFO_MAGIC;
gop->info.version = 0;
gop->info.width = vesa->x_resolution;
gop->info.height = vesa->y_resolution;
gop->info.pixel_format = EFI_GOT_RGBA8;
gop->info.pixels_per_scanline = vesa->bytes_per_scanline / 4;
gop->fb_base = vesa->phys_base_ptr;
gop->fb_size = vesa->bytes_per_scanline * vesa->y_resolution;
}
#endif
/*
* Use bootaddr to find the location in memory that VxWorks
* will look for the bootline string. The default value is
......@@ -257,104 +342,78 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*/
tmp = env_get("bootaddr");
if (!tmp) {
#ifdef CONFIG_X86
bootaddr = base + X86_BOOT_LINE_OFFSET;
#else
printf("## VxWorks bootline address not specified\n");
} else {
return 1;
#endif
}
if (!bootaddr)
bootaddr = simple_strtoul(tmp, NULL, 16);
/*
* Check to see if the bootline is defined in the 'bootargs'
* parameter. If it is not defined, we may be able to
* construct the info.
*/
bootline = env_get("bootargs");
if (bootline) {
memcpy((void *)bootaddr, bootline,
max(strlen(bootline), (size_t)255));
flush_cache(bootaddr, max(strlen(bootline),
(size_t)255));
/*
* Check to see if the bootline is defined in the 'bootargs' parameter.
* If it is not defined, we may be able to construct the info.
*/
bootline = env_get("bootargs");
if (!bootline) {
tmp = env_get("bootdev");
if (tmp) {
strcpy(build_buf, tmp);
ptr = strlen(tmp);
} else {
tmp = env_get("bootdev");
if (tmp) {
strcpy(build_buf, tmp);
ptr = strlen(tmp);
} else
printf("## VxWorks boot device not specified\n");
printf("## VxWorks boot device not specified\n");
}
tmp = env_get("bootfile");
if (tmp)
ptr += sprintf(build_buf + ptr,
"host:%s ", tmp);
else
ptr += sprintf(build_buf + ptr,
"host:vxWorks ");
tmp = env_get("bootfile");
if (tmp)
ptr += sprintf(build_buf + ptr, "host:%s ", tmp);
else
ptr += sprintf(build_buf + ptr, "host:vxWorks ");
/*
* The following parameters are only needed if 'bootdev'
* is an ethernet device, otherwise they are optional.
*/
tmp = env_get("ipaddr");
/*
* The following parameters are only needed if 'bootdev'
* is an ethernet device, otherwise they are optional.
*/
tmp = env_get("ipaddr");
if (tmp) {
ptr += sprintf(build_buf + ptr, "e=%s", tmp);
tmp = env_get("netmask");
if (tmp) {
ptr += sprintf(build_buf + ptr, "e=%s", tmp);
tmp = env_get("netmask");
if (tmp) {
u32 mask = env_get_ip("netmask").s_addr;
ptr += sprintf(build_buf + ptr,
":%08x ", ntohl(mask));
} else {
ptr += sprintf(build_buf + ptr, " ");
}
u32 mask = env_get_ip("netmask").s_addr;
ptr += sprintf(build_buf + ptr,
":%08x ", ntohl(mask));
} else {
ptr += sprintf(build_buf + ptr, " ");
}
}
tmp = env_get("serverip");
if (tmp)
ptr += sprintf(build_buf + ptr, "h=%s ", tmp);
tmp = env_get("gatewayip");
if (tmp)
ptr += sprintf(build_buf + ptr, "g=%s ", tmp);
tmp = env_get("serverip");
if (tmp)
ptr += sprintf(build_buf + ptr, "h=%s ", tmp);
tmp = env_get("hostname");
if (tmp)
ptr += sprintf(build_buf + ptr, "tn=%s ", tmp);
tmp = env_get("gatewayip");
if (tmp)
ptr += sprintf(build_buf + ptr, "g=%s ", tmp);
tmp = env_get("othbootargs");
if (tmp) {
strcpy(build_buf + ptr, tmp);
ptr += strlen(tmp);
}
tmp = env_get("hostname");
if (tmp)
ptr += sprintf(build_buf + ptr, "tn=%s ", tmp);
memcpy((void *)bootaddr, build_buf,
max(strlen(build_buf), (size_t)255));
flush_cache(bootaddr, max(strlen(build_buf),
(size_t)255));
tmp = env_get("othbootargs");
if (tmp) {
strcpy(build_buf + ptr, tmp);
ptr += strlen(tmp);
}
printf("## Using bootline (@ 0x%lx): %s\n", bootaddr,
(char *)bootaddr);
bootline = build_buf;
}
#ifdef CONFIG_X86
/*
* Since E820 information is critical to the kernel, if we don't
* specify these in the environments, use a default one.
*/
tmp = env_get("e820data");
if (tmp)
data = (struct e820entry *)simple_strtoul(tmp, NULL, 16);
else
data = (struct e820entry *)VXWORKS_E820_DATA_ADDR;
tmp = env_get("e820info");
if (tmp)
info = (struct e820info *)simple_strtoul(tmp, NULL, 16);
else
info = (struct e820info *)VXWORKS_E820_INFO_ADDR;
memset(info, 0, sizeof(struct e820info));
info->sign = E820_SIGNATURE;
info->entries = install_e820_map(E820MAX, data);
info->addr = (info->entries - 1) * sizeof(struct e820entry) +
VXWORKS_E820_DATA_ADDR;
#endif
memcpy((void *)bootaddr, bootline, max(strlen(bootline), (size_t)255));
flush_cache(bootaddr, max(strlen(bootline), (size_t)255));
printf("## Using bootline (@ 0x%lx): %s\n", bootaddr, (char *)bootaddr);
/*
* If the data at the load address is an elf image, then
......
......@@ -52,5 +52,5 @@ CONFIG_E1000=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
CONFIG_FRAMEBUFFER_VESA_MODE_11B=y
CONFIG_CONSOLE_SCROLL_LINES=5
......@@ -57,5 +57,5 @@ CONFIG_DEBUG_UART_CLOCK=1843200
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
CONFIG_FRAMEBUFFER_VESA_MODE_11B=y
CONFIG_CONSOLE_SCROLL_LINES=5
......@@ -69,5 +69,5 @@ CONFIG_SPL_TIMER=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_111=y
CONFIG_FRAMEBUFFER_VESA_MODE_112=y
CONFIG_CONSOLE_SCROLL_LINES=5
......@@ -49,5 +49,5 @@ CONFIG_NVME=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_111=y
CONFIG_FRAMEBUFFER_VESA_MODE_112=y
CONFIG_CONSOLE_SCROLL_LINES=5
......@@ -43,7 +43,7 @@ CONFIG_CPU=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_111=y
CONFIG_FRAMEBUFFER_VESA_MODE_112=y
CONFIG_CONSOLE_SCROLL_LINES=5
CONFIG_EFI=y
CONFIG_EFI_STUB=y
......@@ -43,7 +43,7 @@ CONFIG_CPU=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_111=y
CONFIG_FRAMEBUFFER_VESA_MODE_112=y
CONFIG_CONSOLE_SCROLL_LINES=5
CONFIG_EFI=y
CONFIG_EFI_STUB=y
......
......@@ -17,9 +17,7 @@ For booting old kernels (6.9.x) on PowerPC and ARM, and all kernel versions
on other architectures, 'bootvx' shall be used. For booting VxWorks 7 kernels
on PowerPC and ARM, 'bootm' shall be used.
64-bit x86 kernel cannot be loaded as of today.
VxWork 7 on PowerPC and ARM
VxWorks 7 on PowerPC and ARM
---------------------------
From VxWorks 7, VxWorks starts adopting device tree as its hardware decription
mechansim (for PowerPC and ARM), thus requiring boot interface changes.
......@@ -30,11 +28,11 @@ the ePAPR standard, which is shown below (see ePAPR for more details):
void (*kernel_entry)(fdt_addr, 0, 0, EPAPR_MAGIC, boot_IMA, 0, 0)
For ARM, the calling convention is show below:
For ARM, the calling convention is shown below:
void (*kernel_entry)(void *fdt_addr)
When booting new VxWorks kernel (uImage format), the parameters passed to bootm
When booting a VxWorks 7 kernel (uImage format), the parameters passed to bootm
is like below:
bootm <kernel image address> - <device tree address>
......@@ -46,7 +44,7 @@ board-specific address before loading VxWorks. U-Boot supplies its address
via "bootaddr" environment variable. To check where the bootline should be
for a specific board, go to the VxWorks BSP for that board, and look for a
parameter called BOOT_LINE_ADRS. Assign its value to "bootaddr". A typical
value for "bootaddr" is 0x101200.
value for "bootaddr" on an x86 board is 0x101200.
If a "bootargs" variable is defined, its content will be copied to the memory
location pointed by "bootaddr" as the kernel bootline. If "bootargs" is not
......@@ -67,19 +65,34 @@ look like VxWorks hangs somewhere as nothing outputs on the serial console.
x86-specific information
------------------------
Before loading an x86 kernel, two additional environment variables need to be
provided. They are "e820data" and "e820info", which represent the address of
E820 table and E820 information (defined by VxWorks) in system memory.
Check VxWorks kernel configuration to look for BIOS_E820_DATA_START and
BIOS_E820_INFO_START, and assign their values to "e820data" and "e820info"
accordingly. If neither of these two are supplied, U-Boot assumes a default
location at 0x4000 for "e820data" and 0x4a00 for "e820info". Typical values
for "e820data" and "e820info" are 0x104000 and 0x104a00. But there is one
exception on Intel Galileo, where "e820data" and "e820info" should be left
unset, which assume the default location for VxWorks.
Note since currently U-Boot does not support ACPI yet, VxWorks kernel must
Before loading an x86 kernel, one additional environment variable need to be
provided. This is "vx_phys_mem_base", which represent the physical memory
base address of VxWorks.
Check VxWorks kernel configuration to look for LOCAL_MEM_LOCAL_ADRS. For
VxWorks 7, this is normally a virtual address and you need find out its
corresponding physical address and assign its value to "vx_phys_mem_base".
For boards on which ACPI is not supported by U-Boot yet, VxWorks kernel must
be configured to use MP table and virtual wire interrupt mode. This requires
INCLUDE_MPTABLE_BOOT_OP and INCLUDE_VIRTUAL_WIRE_MODE to be included in a
VxWorks kernel configuration.
Both 32-bit x86 and 64-bit x64 kernels can be loaded.
There are two types of graphics console drivers in VxWorks. One is the 80x25
VGA text mode driver. The other one is the EFI console bitmapped graphics mode
driver. To make these drivers function, U-Boot needs to load and run the VGA
BIOS of the graphics card first.
- If the kernel is configured with 80x25 VGA text mode driver,
CONFIG_FRAMEBUFFER_SET_VESA_MODE must be unset in U-Boot.
- If the kernel is configured with bitmapped graphics mode driver,
CONFIG_FRAMEBUFFER_SET_VESA_MODE need remain set but care must be taken
at which VESA mode is to be set. The supported pixel format is 32-bit
RGBA, hence the available VESA mode can only be one of the following:
* FRAMEBUFFER_VESA_MODE_10F
* FRAMEBUFFER_VESA_MODE_112
* FRAMEBUFFER_VESA_MODE_115
* FRAMEBUFFER_VESA_MODE_118
* FRAMEBUFFER_VESA_MODE_11B
......@@ -46,7 +46,7 @@ Build Instructions for U-Boot as coreboot payload
Building U-Boot as a coreboot payload is just like building U-Boot for targets
on other architectures, like below:
$ make coreboot-x86_defconfig
$ make coreboot_defconfig
$ make all
Note this default configuration will build a U-Boot payload for the QEMU board.
......
......@@ -65,6 +65,7 @@ static u32 saveBaseAddress20;
/* Addres im memory of VBE region */
const int vbe_offset = 0x2000;
#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
static const void *bios_ptr(const void *buf, BE_VGAInfo *vga_info,
u32 x86_dword_ptr)
{
......@@ -215,6 +216,7 @@ static int atibios_set_vesa_mode(RMREGS *regs, int vesa_mode,
return 0;
}
#endif /* CONFIG_FRAMEBUFFER_SET_VESA_MODE */
/****************************************************************************
PARAMETERS:
......@@ -263,11 +265,13 @@ static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo *vga_info,
/*Cleanup and exit*/
BE_getVGA(vga_info);
#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
/* Useful for debugging */
if (0)
atibios_debug_mode(vga_info, &regs, vesa_mode, mode_info);
if (vesa_mode != -1)
atibios_set_vesa_mode(&regs, vesa_mode, mode_info);
#endif
}
/****************************************************************************
......
......@@ -355,8 +355,6 @@ int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void))
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
int ret;
printf("Video: ");
/* If we are running from EFI or coreboot, this can't work */
if (!ll_boot_init()) {
printf("Not available (previous bootloader prevents it)\n");
......@@ -377,7 +375,7 @@ int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void))
return ret;
}
printf("%dx%dx%d\n", uc_priv->xsize, uc_priv->ysize,
printf("Video: %dx%dx%d\n", uc_priv->xsize, uc_priv->ysize,
mode_info.vesa.bits_per_pixel);
return 0;
......
......@@ -174,7 +174,7 @@ config FRAMEBUFFER_SET_VESA_MODE
choice
prompt "framebuffer graphics resolution"
default FRAMEBUFFER_VESA_MODE_117
default FRAMEBUFFER_VESA_MODE_118
depends on FRAMEBUFFER_SET_VESA_MODE
help
This option sets the resolution used for the U-Boot framebuffer (and
......
此差异已折叠。
......@@ -8,10 +8,21 @@
#ifndef _VXWORKS_H_
#define _VXWORKS_H_
#include <efi_api.h>
/*
* Physical address of memory base for VxWorks x86
* This is LOCAL_MEM_LOCAL_ADRS in the VxWorks kernel configuration.
*/
#define VXWORKS_PHYS_MEM_BASE 0x100000
/* x86 bootline offset relative to LOCAL_MEM_LOCAL_ADRS in VxWorks */
#define X86_BOOT_LINE_OFFSET 0x1200
/*
* VxWorks x86 E820 related stuff
*
* VxWorks on x86 gets E820 information from pre-defined address @
* VxWorks on x86 gets E820 information from pre-defined offset @
* 0x4a00 and 0x4000. At 0x4a00 it's an information table defined
* by VxWorks and the actual E820 table entries starts from 0x4000.
* As defined by the BIOS E820 spec, the maximum number of E820 table
......@@ -20,13 +31,13 @@
* information that is retrieved from the BIOS E820 call and saved
* later for sanity test during the kernel boot-up.
*/
#define VXWORKS_E820_DATA_ADDR 0x4000
#define VXWORKS_E820_INFO_ADDR 0x4a00
#define E820_DATA_OFFSET 0x4000
#define E820_INFO_OFFSET 0x4a00
/* E820 info signatiure "SMAP" - System MAP */
#define E820_SIGNATURE 0x534d4150
struct e820info {
struct e820_info {
u32 sign; /* "SMAP" signature */
u32 x0; /* don't care, used by VxWorks */
u32 x1; /* don't care, used by VxWorks */
......@@ -37,6 +48,39 @@ struct e820info {
u32 error; /* must be zero */
};
/*
* VxWorks bootloader stores its size at a pre-defined offset @ 0x5004.
* Later when VxWorks kernel boots up and system memory information is
* retrieved from the E820 table, the bootloader size will be subtracted
* from the total system memory size to calculate the size of available
* memory for the OS.
*/
#define BOOT_IMAGE_SIZE_OFFSET 0x5004
/*
* When booting from EFI BIOS, VxWorks bootloader stores the EFI GOP
* framebuffer info at a pre-defined offset @ 0x6100. When VxWorks kernel
* boots up, its EFI console driver tries to find such a block and if
* the signature matches, the framebuffer information will be used to
* initialize the driver.
*
* However it is not necessary to prepare an EFI environment for VxWorks's
* EFI console driver to function (eg: EFI loader in U-Boot). If U-Boot has
* already initialized the graphics card and set it to a VESA mode that is
* compatible with EFI GOP, we can simply prepare such a block for VxWorks.
*/
#define EFI_GOP_INFO_OFFSET 0x6100
/* EFI GOP info signatiure */
#define EFI_GOP_INFO_MAGIC 0xfeedface
struct efi_gop_info {
u32 magic; /* signature */
struct efi_gop_mode_info info; /* EFI GOP mode info structure */
phys_addr_t fb_base; /* framebuffer base address */
u32 fb_size; /* framebuffer size */
};
int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
void boot_prep_vxworks(bootm_headers_t *images);
void boot_jump_vxworks(bootm_headers_t *images);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册