diff -Naur grub-0.97/stage2/boot.c grub-0.97-GX1/stage2/boot.c --- grub-0.97/stage2/boot.c 2004-03-30 13:44:08.000000000 +0200 +++ grub-0.97-GX1/stage2/boot.c 2007-10-21 22:28:47.000000000 +0200 @@ -29,6 +29,7 @@ entry_func entry_addr; static struct mod_list mll[99]; static int linux_mem_size; +unsigned int geode_mem = 0; /* * The next two functions, 'load_image' and 'load_module', are the building @@ -423,8 +424,7 @@ 3) GNU GRUB is configured not to pass the "mem" option. 4) The kernel supports boot protocol 2.03 or newer. */ if (! grub_strstr (arg, "mem=") - && ! (load_flags & KERNEL_LOAD_NO_MEM_OPTION) - && lh->version < 0x0203 /* kernel version < 2.4.18 */ + && geode_mem > 0 && dest + 15 < linux_data_tmp_addr + LINUX_CL_END_OFFSET) { *dest++ = ' '; @@ -433,8 +433,9 @@ *dest++ = 'm'; *dest++ = '='; - dest = convert_to_ascii (dest, 'u', (extended_memory + 0x400)); + dest = convert_to_ascii (dest, 'u', geode_mem); *dest++ = 'K'; + linux_mem_size = geode_mem * 1024; } *dest = 0; diff -Naur grub-0.97/stage2/builtins.c grub-0.97-GX1/stage2/builtins.c --- grub-0.97/stage2/builtins.c 2005-02-15 22:58:23.000000000 +0100 +++ grub-0.97-GX1/stage2/builtins.c 2007-10-21 22:28:34.000000000 +0200 @@ -27,6 +27,8 @@ #include #include #include +#include +#include "../netboot/osdep.h" #ifdef SUPPORT_NETBOOT # define GRUB 1 @@ -78,6 +80,8 @@ /* The BIOS drive map. */ static unsigned short bios_drive_map[DRIVE_MAP_SIZE + 1]; +extern unsigned int geode_mem; + /* Prototypes for allowing straightfoward calling of builtins functions inside other functions. */ static int configfile_func (char *arg, int flags); @@ -1331,6 +1335,83 @@ }; +/* Geode GX1 video RAM hack */ +static int +geode_mem_func (char *arg, int flags) +{ + unsigned char gcr, lock; + unsigned short unlock; + unsigned short memsize = 0; + unsigned int gx_base, gx_bank, old_pg, new_pg; + unsigned int fbsize = 0; + + if (!safe_parse_maxint(&arg, &fbsize)) + { + errnum = ERR_BAD_ARGUMENT; + return 1; + } + + /* Max allowed FB size is 4Mb */ + fbsize = ( fbsize > 4096 ) ? 4096 : fbsize; + + /* Find GX_BASE GCR register (from NSC Linux framebuffer driver) */ + outb(GX_CCR3, GX_CSCIR); + lock = inb(GX_CSCDR); + outb(GX_CCR3, GX_CSCIR); + outb((unsigned char)(lock | 0x10), GX_CSCDR); + outb(GX_GCR, GX_CSCIR); + gcr = inb(GX_CSCDR); + outb(GX_CCR3, GX_CSCIR); + outb(lock, GX_CSCDR); + + gx_base = (gcr & 3) << 30; + grub_printf("GX_BASE = %x\n", gx_base); + + grub_printf("BC_DRAM_TOP = %x\n", readl(gx_base + BC_DRAM_TOP)); + + old_pg = readl(gx_base + MC_GBASE_ADD); + grub_printf("MC_GBASE_ADD = %x\n", old_pg); + + /* Calculate installed memory using MC_BANK_CFG register */ + gx_bank = readl(gx_base + MC_BANK_CFG); + if ( (gx_bank & 0x00000070) ^ 0x00000070 ) + { + memsize += 1 << (((gx_bank & 0x00000700) >> 8) + 2); + } + if ( ( gx_bank & 0x00700000 ) ^ 0x00700000 ) + { + memsize += 1 << (((gx_bank & 0x07000000) >> 24) + 2); + } + + grub_printf("MC_BANK_CFG reports %dMb of memory\n", memsize); + grub_printf("Using a %dkb frame buffer\n", fbsize); + + /* Save total available RAM for Linux kernel command line */ + geode_mem = (memsize * 1024) - fbsize; + + /* Write graphics base address */ + unlock = readl(gx_base + DC_UNLOCK); + writel(DC_UNLOCK_MAGIC, gx_base + DC_UNLOCK); + writel((memsize*1024 - fbsize)*1024-1, gx_base + BC_DRAM_TOP); + new_pg = (memsize*1024 - fbsize) / 512; + writel(new_pg, gx_base + MC_GBASE_ADD); + writel(unlock, gx_base + DC_UNLOCK); + + grub_printf("New MC_GBASE_ADD = %x\n", new_pg); + + return 0; +} + +static struct builtin builtin_geode_mem = +{ + "geode_mem", + geode_mem_func, + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, + "geode_mem VIDEORAM", + "Set Geode GX1 video framebuffer size (in kilobytes)." +}; + + /* geometry */ static int geometry_func (char *arg, int flags) @@ -4822,6 +4903,7 @@ &builtin_fallback, &builtin_find, &builtin_fstest, + &builtin_geode_mem, &builtin_geometry, &builtin_halt, &builtin_help, diff -Naur grub-0.97/stage2/geode.h grub-0.97-GX1/stage2/geode.h --- grub-0.97/stage2/geode.h 1970-01-01 01:00:00.000000000 +0100 +++ grub-0.97-GX1/stage2/geode.h 2007-10-20 22:56:33.000000000 +0200 @@ -0,0 +1,17 @@ +/* Geode GX1 defines */ +#define GX_CSCIR 0x22 /* Chip Setup and Control Index Register */ +#define GX_CSCDR 0x23 /* Chip Setup and Control Data Register */ + +#define GX_GCR 0xb8 +#define GX_CCR3 0xc3 + +#define DC_UNLOCK 0x8300 +#define DC_UNLOCK_MAGIC 0x4758 +#define BC_DRAM_TOP 0x8000 +#define MC_GBASE_ADD 0x8414 +#define MC_BANK_CFG 0x8408 + +#define DC_FB_OFFSET 0x800000 + +#define FB_MAX_SIZE 4096 /* Maximum framebuffer size */ +#define BOOTSPLASH_SIZE 640*480 /* Vendor bootsplash size */