diff -burN skyeye-v1-orig/arch/arm/common/arm_arch_interface.c skyeye-v1/arch/arm/common/arm_arch_interface.c --- skyeye-v1-orig/arch/arm/common/arm_arch_interface.c 2005-10-10 07:04:10.000000000 +0200 +++ skyeye-v1/arch/arm/common/arm_arch_interface.c 2005-11-23 00:09:24.000000000 +0100 @@ -8,6 +8,15 @@ mem_config_t arm_mem; cpu_config_t *p_arm_cpu; extern ARMword skyeye_cachetype; + +static ARMword parse_address(const char *value) +{ + if (value[0] == '0' && value[1] == 'x') + return strtoul (value, NULL, 16); + else + return strtoul (value, NULL, 10); +} + //chy 2005-08-01, borrow from wlm's 2005-07-26's change static void base_termios_exit (void) @@ -305,24 +314,22 @@ } } else if (!strncmp ("addr", name, strlen (name))) { - - if (value[0] == '0' && value[1] == 'x') - mb[num].addr = strtoul (value, NULL, 16); - else - mb[num].addr = strtoul (value, NULL, 10); - + mb[num].addr = parse_address(value); + printf("Bank %d @ %x\n", num, mb[num].addr); } else if (!strncmp ("size", name, strlen (name))) { - - if (value[0] == '0' && value[1] == 'x') - mb[num].len = strtoul (value, NULL, 16); - else - mb[num].len = strtoul (value, NULL, 10); + mb[num].len = parse_address(value); + printf("Bank %d len %x\n", num, mb[num].len); } else if (!strncmp ("file", name, strlen (name))) { strncpy (mb[num].filename, value, strlen (value) + 1); } + else if (!strncmp ("initrd", name, strlen (name))) + { + if (!strncmp ("yes", value, strlen (value))) + mb[num].usage |= MEMUSAGE_INITRD; + } else if (!strncmp ("boot", name, strlen (name))) { /*this must be the last parameter. */ if (!strncmp ("yes", value, strlen (value))) @@ -338,6 +345,28 @@ return 0; } +static int arm_get_mem(int bank, int type, int usage, WORD *addr, WORD *len) +{ + mem_config_t *mc = &arm_mem; + mem_bank_t *mb = mc->mem_banks; + + for (;bank < MAX_BANK; bank++) { + if ((type==MEMTYPE_ANY || mb[bank].type == type) && + (usage == MEMUSAGE_ANY || usage & mb[bank].usage)) { + *addr = mb[bank].addr; + *len = mb[bank].len; + return bank + 1; + } + } + return 0; +} + +static void +arm_set_kernel_params (WORD addr) +{ + state->Reg[2] = addr; +} + void init_arm_arch () { @@ -353,6 +382,8 @@ arm_arch.parse_cpu = arm_parse_cpu; arm_arch.parse_mach = arm_parse_mach; arm_arch.parse_mem = arm_parse_mem; + arm_arch.get_mem = arm_get_mem; + arm_arch.set_kernel_parameters = arm_set_kernel_params; register_arch (&arm_arch); } diff -burN skyeye-v1-orig/arch/arm/common/armdefs.h skyeye-v1/arch/arm/common/armdefs.h --- skyeye-v1-orig/arch/arm/common/armdefs.h 2005-10-24 15:28:57.000000000 +0200 +++ skyeye-v1/arch/arm/common/armdefs.h 2005-11-23 00:00:09.000000000 +0100 @@ -186,6 +186,7 @@ unsigned long addr, len; char filename[MAX_STR]; unsigned type; //chy 2003-09-21: maybe io,ram,rom + int usage; } mem_bank_t; typedef struct diff -burN skyeye-v1-orig/Makefile skyeye-v1/Makefile --- skyeye-v1-orig/Makefile 2005-10-08 09:53:05.000000000 +0200 +++ skyeye-v1/Makefile 2005-11-21 22:43:27.000000000 +0100 @@ -112,7 +112,7 @@ SIM_DEVICE_OBJS = binary/skyeye_device.o $(SIM_NET_OBJS) $(SIM_LCD_OBJS) $(SIM_FLASH_OBJS) -SIM_UTILS_OBJS = binary/skyeye2gdb.o binary/skyeye_config.o binary/skyeye_options.o binary/skyeye_stub_win32.o binary/skyeye.o binary/skyeye_arch.o +SIM_UTILS_OBJS = binary/skyeye2gdb.o binary/skyeye_config.o binary/skyeye_options.o binary/skyeye_stub_win32.o binary/skyeye.o binary/skyeye_arch.o binary/kernel_parameters.o SIM_OBJS = $(SIM_ARM_OBJS) \ $(SIM_MMU_OBJS) \ @@ -229,6 +229,10 @@ binary/skyeye_options.o: $(UTILS_PATH)/config/skyeye_options.c $(UTILS_PATH)/config/skyeye_config.h \ $(ARM_COMMON_PATH)/armdefs.h $(ARM_COMMON_PATH)/armmem.h $(ARM_COMMON_PATH)/armio.h $(CC) -c $< -o $@ $(ALL_CFLAGS) +binary/kernel_parameters.o: $(UTILS_PATH)/config/kernel_parameters.c $(UTILS_PATH)/config/skyeye_config.h \ + $(ARM_COMMON_PATH)/armdefs.h $(ARM_COMMON_PATH)/armmem.h $(ARM_COMMON_PATH)/armio.h + $(CC) -c $< -o $@ $(ALL_CFLAGS) + binary/skyeye_arch.o:$(UTILS_PATH)/config/skyeye_arch.c $(CC) -c $< -o $@ $(ALL_CFLAGS) diff -burN skyeye-v1-orig/utils/config/kernel_parameters.c skyeye-v1/utils/config/kernel_parameters.c --- skyeye-v1-orig/utils/config/kernel_parameters.c 1970-01-01 01:00:00.000000000 +0100 +++ skyeye-v1/utils/config/kernel_parameters.c 2005-11-23 00:20:54.000000000 +0100 @@ -0,0 +1,233 @@ +/* +Based on code from +http://www.simtec.co.uk/products/SWLINUX/files/booting_article.htm +*/ + +#include "skyeye_config.h" + +/* list of possible tags */ +#define ATAG_NONE 0x00000000 +#define ATAG_CORE 0x54410001 +#define ATAG_MEM 0x54410002 +#define ATAG_VIDEOTEXT 0x54410003 +#define ATAG_RAMDISK 0x54410004 +#define ATAG_INITRD2 0x54420005 +#define ATAG_SERIAL 0x54410006 +#define ATAG_REVISION 0x54410007 +#define ATAG_VIDEOLFB 0x54410008 +#define ATAG_CMDLINE 0x54410009 + +/* structures for each atag */ +struct atag_header { + u32 size; /* length of tag in words including this header */ + u32 tag; /* tag type */ +}; + +struct atag_core { + u32 flags; + u32 pagesize; + u32 rootdev; +}; + +struct atag_mem { + u32 size; + u32 start; +}; + +struct atag_videotext { + u8 x; + u8 y; + u16 video_page; + u8 video_mode; + u8 video_cols; + u16 video_ega_bx; + u8 video_lines; + u8 video_isvga; + u16 video_points; +}; + +struct atag_ramdisk { + u32 flags; + u32 size; + u32 start; +}; + +struct atag_initrd2 { + u32 start; + u32 size; +}; + +struct atag_serialnr { + u32 low; + u32 high; +}; + +struct atag_revision { + u32 rev; +}; + +struct atag_videolfb { + u16 lfb_width; + u16 lfb_height; + u16 lfb_depth; + u16 lfb_linelength; + u32 lfb_base; + u32 lfb_size; + u8 red_size; + u8 red_pos; + u8 green_size; + u8 green_pos; + u8 blue_size; + u8 blue_pos; + u8 rsvd_size; + u8 rsvd_pos; +}; + +struct atag_cmdline { + char cmdline[1]; +}; + +struct atag { + struct atag_header hdr; + union { + struct atag_core core; + struct atag_mem mem; + struct atag_videotext videotext; + struct atag_ramdisk ramdisk; + struct atag_initrd2 initrd2; + struct atag_serialnr serialnr; + struct atag_revision revision; + struct atag_videolfb videolfb; + struct atag_cmdline cmdline; + } u; +}; + + +#define tag_next(t) ((struct atag *)((u32 *)(t) + (t)->hdr.size)) +#define tag_size(type) ((sizeof(struct atag_header) + sizeof(struct type)) >> 2) +static struct atag *params; /* used to point at the current tag */ + +static void +setup_core_tag(void * address,long pagesize) +{ + params = (struct atag *)address; /* Initialise parameters to start at given address */ + + params->hdr.tag = ATAG_CORE; /* start with the core tag */ + params->hdr.size = tag_size(atag_core); /* size the tag */ + + params->u.core.flags = 1; /* ensure read-only */ + params->u.core.pagesize = pagesize; /* systems pagesize (4k) */ + params->u.core.rootdev = 0; /* zero root device (typicaly overidden from commandline )*/ + + params = tag_next(params); /* move pointer to next tag */ +} + +static void +setup_ramdisk_tag(u32 size) +{ + params->hdr.tag = ATAG_RAMDISK; /* Ramdisk tag */ + params->hdr.size = tag_size(atag_ramdisk); /* size tag */ + + params->u.ramdisk.flags = 0; /* Load the ramdisk */ + params->u.ramdisk.size = size; /* Decompressed ramdisk size */ + params->u.ramdisk.start = 0; /* Unused */ + + params = tag_next(params); /* move pointer to next tag */ +} + +static void +setup_initrd2_tag(u32 start, u32 size) +{ + params->hdr.tag = ATAG_INITRD2; /* Initrd2 tag */ + params->hdr.size = tag_size(atag_initrd2); /* size tag */ + + params->u.initrd2.start = start; /* physical start */ + params->u.initrd2.size = size; /* compressed ramdisk size */ + + params = tag_next(params); /* move pointer to next tag */ +} + +static void +setup_mem_tag(u32 start, u32 len) +{ + params->hdr.tag = ATAG_MEM; /* Memory tag */ + params->hdr.size = tag_size(atag_mem); /* size tag */ + + params->u.mem.start = start; /* Start of memory area (physical address) */ + params->u.mem.size = len; /* Length of area */ + + params = tag_next(params); /* move pointer to next tag */ +} + +static void +setup_cmdline_tag(const char * line) +{ + int linelen = strlen(line); + + if(!linelen) + return; /* do not insert a tag for an empty commandline */ + + params->hdr.tag = ATAG_CMDLINE; /* Commandline tag */ + params->hdr.size = (sizeof(struct atag_header) + linelen + 1 + 4) >> 2; + strcpy(params->u.cmdline.cmdline,line); /* place commandline into tag */ + + params = tag_next(params); /* move pointer to next tag */ +} + +static void +setup_end_tag(void) +{ + params->hdr.tag = ATAG_NONE; /* Empty tag ends list */ + params->hdr.size = 0; /* zero length */ +} + + +static int notify_membank(skyeye_config_t* pConfig, int type, int usage, void (*setupFn)(u32 addr, u32 len)) +{ + int i=0; + int found=0; + WORD addr, len; + + do { + i=pConfig->arch->get_mem(i, type, usage, &addr, &len); + if (i>0) { + setupFn(addr, len); + found++; + } + } while(i>0); + return found; +} + +void +configure_kernel(skyeye_config_t* pConfig, generic_arch_t *pArch) +{ + char paramBuf[2048]; + int i; + + memset(paramBuf, 0, sizeof(paramBuf)); + + printf("configuring kernel parameter block=%08X cmdline:%s\n", + pConfig->kernel_parameters_address, pConfig->kernel_ccommand_line); + if (pConfig->kernel_parameters_address == 0) + { + printf("No kernel parameter address\n"); + return; + } + setup_core_tag(paramBuf, 4096); /* standard core tag 4k pagesize */ + + notify_membank(pConfig, MEMTYPE_RAM, MEMUSAGE_ANY, setup_mem_tag); + if (notify_membank(pConfig, MEMTYPE_ANY, MEMUSAGE_INITRD, setup_initrd2_tag)) { + setup_ramdisk_tag(pConfig->initrd_kb); + } + + setup_cmdline_tag(pConfig->kernel_ccommand_line); + setup_end_tag(); + + for (i = 0; i < sizeof(paramBuf); i++) { + pArch->write_byte (pConfig->kernel_parameters_address + i, paramBuf[i]); + } + pConfig->arch->set_kernel_parameters(pConfig->kernel_parameters_address); + +} + + diff -burN skyeye-v1-orig/utils/config/skyeye_config.c skyeye-v1/utils/config/skyeye_config.c --- skyeye-v1-orig/utils/config/skyeye_config.c 2005-10-10 07:04:10.000000000 +0200 +++ skyeye-v1/utils/config/skyeye_config.c 2005-11-22 21:47:23.000000000 +0100 @@ -32,7 +32,7 @@ //int skyeye_instr_debug=0; FILE *skyeye_logfd; - /**/ int +int parse_line_unformatted (char *line) { #define MAX_PARAMS_LEN 40 @@ -60,7 +60,7 @@ ptr = strtok (line, ":"); while ((ptr) && (!comment)) { - string_i = 0; + if (! inquotes) string_i = 0; for (i = 0; i < strlen (ptr); i++) { if (ptr[i] == '"') inquotes = !inquotes; @@ -73,6 +73,12 @@ string[string_i++] = ptr[i]; } } + if (inquotes) { + string[string_i++] = ','; + ptr = strtok (NULL, ","); + continue; + } + string[string_i] = '\0'; if (string_i == 0) break; @@ -91,6 +97,7 @@ } strncpy (params[num_params], string, string_i); params[num_params][string_i] = '\0'; + printf("*** got param %s\n", params[num_params]); num_params++; ptr = strtok (NULL, ","); } diff -burN skyeye-v1-orig/utils/config/skyeye_config.h skyeye-v1/utils/config/skyeye_config.h --- skyeye-v1-orig/utils/config/skyeye_config.h 2005-10-24 15:28:57.000000000 +0200 +++ skyeye-v1/utils/config/skyeye_config.h 2005-11-23 00:10:02.000000000 +0100 @@ -141,6 +141,7 @@ #define MAX_BANK 8 #define MAX_STR 1024 +#define MEMTYPE_ANY -1 #define MEMTYPE_IO 0 #define MEMTYPE_RAM 1 #define MEMTYPE_ROM 2 @@ -148,6 +149,9 @@ /*ywc 2005-03-30*/ #define MEMTYPE_FLASH 3 +#define MEMUSAGE_INITRD 1 +#define MEMUSAGE_ANY -1 + /*ksh 2004-11-26,energy profile flag*/ typedef struct { @@ -225,6 +229,8 @@ int do_log_option (); int do_step_disassemble_option (); +int do_kernel_parameters_option (); + //teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- #ifdef DBCT_TEST_SPEED int do_dbct_test_speed_sec(); @@ -232,7 +238,7 @@ //AJ2D-------------------------------------------------------------------------- #define MAX_OPTION_NAME 32 -#define MAX_PARAM_NAME 32 +#define MAX_PARAM_NAME 256 typedef struct skyeye_option_t { @@ -256,19 +262,22 @@ int (*parse_cpu) (const char *param[]); int (*parse_mach) (machine_config_t * mach, const char *param[]); int (*parse_mem) (int num_params, const char *params[]); + int (*get_mem) (int bank, int type, int usage, WORD *addr, WORD *len); // obtain first RAM bank from bank return next bank or 0 + void (*set_kernel_parameters) (WORD addr); } arch_config_t; typedef struct { arch_config_t *arch; //cpu_config_t *cpu; machine_config_t *mach; - //mem_config_t mem; + // mem_config_t mem; //chy 2003-09-12, now support more io banks // ioaddr_config_t ioaddr; //used for ARMul_notIOaddr funciton net_config_t net[NET_MAXNICNUM_PER_HOST]; uart_config_t uart; log_config_t log; ARMword start_address; + ARMword initrd_address; /*ywc 2005-03-31, no_dbct used by Dynamic Binary Code Translation */ ARMword no_dbct; @@ -283,6 +292,11 @@ //teawater add for new tb manage function 2005.07.10---------------------------- uint32_t tb_tbt_size; uint32_t tb_tbp_size; + + ARMword kernel_parameters_address; + char kernel_ccommand_line[256]; + int initrd_kb; + //teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- #ifdef DBCT_TEST_SPEED long dbct_test_speed_sec; @@ -320,6 +334,7 @@ */ //teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- {"step_disassemble", do_step_disassemble_option, 0, 1}, + {"kernel_parameters", do_kernel_parameters_option, 0, 1} #ifdef DBCT_TEST_SPEED {"dbct_test_speed_sec", do_dbct_test_speed_sec, 0, 1}, #endif //DBCT_TEST_SPEED diff -burN skyeye-v1-orig/utils/config/skyeye_options.c skyeye-v1/utils/config/skyeye_options.c --- skyeye-v1-orig/utils/config/skyeye_options.c 2005-10-24 15:28:57.000000000 +0200 +++ skyeye-v1/utils/config/skyeye_options.c 2005-11-23 00:05:37.000000000 +0100 @@ -45,7 +45,6 @@ { const char *src = param; char *dst = name; - while (*src && (*src != '=')) *dst++ = *src++; *dst = '\0'; @@ -59,6 +58,13 @@ return 0; } +static unsigned int parse_address(const char *value) +{ + if (value[0] == '0' && value[1] == 'x') + return strtoul (value, NULL, 16); + else + return strtoul (value, NULL, 10); +} /* we need init some options before read the option file. * now put them here. @@ -247,6 +253,51 @@ } int +do_kernel_parameters_option (skyeye_option_t * this_option, int num_params, + const char *params[]) +{ + + int i; + char name[MAX_PARAM_NAME], value[MAX_PARAM_NAME]; + int ret = 0; + + for (i = 0; i < num_params; i++) { + if (split_param (params[i], name, value) < 0) + { + ret=1; + SKYEYE_ERR + ("kernel_parameters: Error: wrong parameter \"%s\".\n", name); + continue; + } + + if (!strncmp ("addr", name, strlen (name))) + { + skyeye_config.kernel_parameters_address = parse_address(value); + continue; + } + + if (!strncmp ("default_cmdline", name, strlen (name))) + { + if (strlen(skyeye_config.kernel_ccommand_line) == 0) + { + strncpy(skyeye_config.kernel_ccommand_line, value, sizeof(skyeye_config.kernel_ccommand_line)-1); + } else { + printf("ignoring config file kernel command line - using %s\n",skyeye_config.kernel_ccommand_line); + } + } + + if (!strncmp ("initrd_kb", name, strlen (name))) + { + sscanf (value, "%u", &skyeye_config.initrd_kb); + } + + } + return ret; + +} + + +int do_mach_option (skyeye_option_t * this_option, int num_params, const char *params[]) { diff -burN skyeye-v1-orig/utils/main/skyeye.c skyeye-v1/utils/main/skyeye.c --- skyeye-v1-orig/utils/main/skyeye.c 2005-10-10 07:04:10.000000000 +0200 +++ skyeye-v1/utils/main/skyeye.c 2005-11-22 22:14:08.000000000 +0100 @@ -311,6 +311,8 @@ //teawater add for load elf 2005.07.31------------------------------------------ char *exec_file = NULL; + memset(&skyeye_config, 0, sizeof(skyeye_config)); + while ((c = getopt (argc, argv, "e:dc:h")) != -1) //AJ2D-------------------------------------------------------------------------- switch (c) { @@ -345,8 +347,10 @@ debugmode, skyeye_config_filename); for (index = optind; index < argc; index++) - printf ("Non-option argument %s\n", argv[index]); - + { + strcat(skyeye_config.kernel_ccommand_line, argv[index]); + strcat(skyeye_config.kernel_ccommand_line, " "); + } init (); //teawater add for load elf 2005.07.31------------------------------------------ @@ -361,6 +365,8 @@ if (skyeye_config.start_address != 0) arch_instance->set_pc (skyeye_config.start_address); + configure_kernel(&skyeye_config, arch_instance); + if (debugmode == 0) sim_resume (0); else