From: wdenk Date: Fri, 25 Jan 2002 00:41:44 +0000 (+0000) Subject: * Enable interrupts before starting IH_TYPE_STANDALONE images X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=1bf9c7499661c95658368d19405b0e68f1067576;p=users%2Frw%2Fppcboot.git * Enable interrupts before starting IH_TYPE_STANDALONE images * Flush caches after loading images --- diff --git a/CHANGELOG b/CHANGELOG index a5800e9..7c1acfd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,10 @@ Modifications for 1.1.5: ====================================================================== +* Enable interrupts before starting IH_TYPE_STANDALONE images + +* Flush caches after loading images + * Fix output of "iminfo" for script images * Include all the 8260 clocks in the "bdinfo" output diff --git a/common/cmd_boot.c b/common/cmd_boot.c index 00242d3..f781b06 100644 --- a/common/cmd_boot.c +++ b/common/cmd_boot.c @@ -272,8 +272,8 @@ load_serial (ulong offset) } if ((store_addr) < start_addr) start_addr = store_addr; - if ((store_addr+binlen-1) > end_addr) - end_addr = store_addr+binlen-1; + if ((store_addr + binlen - 1) > end_addr) + end_addr = store_addr + binlen - 1; break; case SREC_END2: case SREC_END3: @@ -284,9 +284,10 @@ load_serial (ulong offset) "## Last Load Addr = 0x%08lx\n" "## Total Size = 0x%08lx = %ld Bytes\n", start_addr, end_addr, - end_addr-start_addr+1, - end_addr-start_addr+1 + end_addr - start_addr + 1, + end_addr - start_addr + 1 ); + flush_cache (addr, end_addr - start_addr + 1); return (addr); case SREC_START: break; @@ -327,7 +328,7 @@ read_record (char *buf, ulong len) *p = c; } - // Check for the console hangup (if any different from serial) + /* Check for the console hangup (if any different from serial) */ if (bd_ptr->bi_mon_fnc->getc != serial_getc) { @@ -456,78 +457,78 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *ar } -static ulong -load_serial_bin (ulong offset) +static ulong load_serial_bin (ulong offset) { - set_kerm_bin_mode((ulong *)offset); - k_recv(); - return offset; + int size; + + set_kerm_bin_mode ((ulong *) offset); + size = k_recv (); + flush_cache (offset, size); + return offset; } -void send_pad(void) +void send_pad (void) { - int count = his_pad_count; - while (count-- > 0) serial_putc(his_pad_char); + int count = his_pad_count; + + while (count-- > 0) + serial_putc (his_pad_char); } /* converts escaped kermit char to binary char */ -char ktrans(char in) +char ktrans (char in) { - if ((in & 0x60) == 0x40) - { - return (char) (in & ~0x40); - } - else if ((in & 0x7f) == 0x3f) - { - return (char) (in | 0x40); - } - else return in; + if ((in & 0x60) == 0x40) { + return (char) (in & ~0x40); + } else if ((in & 0x7f) == 0x3f) { + return (char) (in | 0x40); + } else + return in; } -int chk1(char *buffer) +int chk1 (char *buffer) { - int total = 0; - while (*buffer) - { - total += *buffer++; - } - return (int) ((total + ((total >> 6) & 0x03)) & 0x3f); + int total = 0; + + while (*buffer) { + total += *buffer++; + } + return (int) ((total + ((total >> 6) & 0x03)) & 0x3f); } -void s1_sendpacket(char *packet) +void s1_sendpacket (char *packet) { - send_pad(); - while (*packet) - { - serial_putc(*packet++); - } + send_pad (); + while (*packet) { + serial_putc (*packet++); + } } static char a_b[24]; -void send_ack(int n) +void send_ack (int n) { - a_b[0] = START_CHAR; - a_b[1] = tochar(3); - a_b[2] = tochar(n); - a_b[3] = ACK_TYPE; - a_b[4] = '\0'; - a_b[4] = tochar(chk1(&a_b[1])); - a_b[5] = his_eol; - a_b[6] = '\0'; - s1_sendpacket(a_b); + a_b[0] = START_CHAR; + a_b[1] = tochar (3); + a_b[2] = tochar (n); + a_b[3] = ACK_TYPE; + a_b[4] = '\0'; + a_b[4] = tochar (chk1 (&a_b[1])); + a_b[5] = his_eol; + a_b[6] = '\0'; + s1_sendpacket (a_b); } -void send_nack(int n) +void send_nack (int n) { - a_b[0] = START_CHAR; - a_b[1] = tochar(3); - a_b[2] = tochar(n); - a_b[3] = NACK_TYPE; - a_b[4] = '\0'; - a_b[4] = tochar(chk1(&a_b[1])); - a_b[5] = his_eol; - a_b[6] = '\0'; - s1_sendpacket(a_b); + a_b[0] = START_CHAR; + a_b[1] = tochar (3); + a_b[2] = tochar (n); + a_b[3] = NACK_TYPE; + a_b[4] = '\0'; + a_b[4] = tochar (chk1 (&a_b[1])); + a_b[5] = his_eol; + a_b[6] = '\0'; + s1_sendpacket (a_b); } @@ -537,94 +538,87 @@ void send_nack(int n) if image is binary, no header is stored in os_data_header. */ -void (*os_data_init)(void); -void (*os_data_char)(char new_char); +void (*os_data_init) (void); +void (*os_data_char) (char new_char); static int os_data_state, os_data_state_saved; int os_data_count; static int os_data_count_saved; static char *os_data_addr, *os_data_addr_saved; static char *bin_start_address; int os_data_header[8]; -void image_data_init(void) +void image_data_init (void) { - os_data_state = 0; - os_data_count = 32; - os_data_addr = (char *) os_data_header; + os_data_state = 0; + os_data_count = 32; + os_data_addr = (char *) os_data_header; } -void bin_data_init(void) +void bin_data_init (void) { - os_data_state = 0; - os_data_count = 0; - os_data_addr = bin_start_address; + os_data_state = 0; + os_data_count = 0; + os_data_addr = bin_start_address; } -void os_data_save(void) +void os_data_save (void) { - os_data_state_saved = os_data_state; - os_data_count_saved = os_data_count; - os_data_addr_saved = os_data_addr; + os_data_state_saved = os_data_state; + os_data_count_saved = os_data_count; + os_data_addr_saved = os_data_addr; } -void os_data_restore(void) +void os_data_restore (void) { - os_data_state = os_data_state_saved; - os_data_count = os_data_count_saved; - os_data_addr = os_data_addr_saved; + os_data_state = os_data_state_saved; + os_data_count = os_data_count_saved; + os_data_addr = os_data_addr_saved; } -void bin_data_char(char new_char) +void bin_data_char (char new_char) { - switch (os_data_state) - { - case 0: /* data */ - *os_data_addr++ = new_char; - --os_data_count; - break; - } + switch (os_data_state) { + case 0: /* data */ + *os_data_addr++ = new_char; + --os_data_count; + break; + } } -void set_kerm_bin_mode(unsigned long *addr) +void set_kerm_bin_mode (unsigned long *addr) { - bin_start_address = (char *) addr; - os_data_init = bin_data_init; - os_data_char = bin_data_char; + bin_start_address = (char *) addr; + os_data_init = bin_data_init; + os_data_char = bin_data_char; } /* k_data_* simply handles the kermit escape translations */ static int k_data_escape, k_data_escape_saved; -void k_data_init(void) +void k_data_init (void) { - k_data_escape = 0; - os_data_init(); + k_data_escape = 0; + os_data_init (); } -void k_data_save(void) +void k_data_save (void) { - k_data_escape_saved = k_data_escape; - os_data_save(); + k_data_escape_saved = k_data_escape; + os_data_save (); } -void k_data_restore(void) +void k_data_restore (void) { - k_data_escape = k_data_escape_saved; - os_data_restore(); + k_data_escape = k_data_escape_saved; + os_data_restore (); } -void k_data_char(char new_char) +void k_data_char (char new_char) { - if (k_data_escape) - { - /* last char was escape - translate this character */ - os_data_char(ktrans(new_char)); - k_data_escape = 0; - } - else - { - if (new_char == his_quote) - { - /* this char is escape - remember */ - k_data_escape = 1; - } - else - { - /* otherwise send this char as-is */ - os_data_char(new_char); - } - } + if (k_data_escape) { + /* last char was escape - translate this character */ + os_data_char (ktrans (new_char)); + k_data_escape = 0; + } else { + if (new_char == his_quote) { + /* this char is escape - remember */ + k_data_escape = 1; + } else { + /* otherwise send this char as-is */ + os_data_char (new_char); + } + } } #define SEND_DATA_SIZE 20 @@ -633,252 +627,258 @@ char *send_ptr; /* handle_send_packet interprits the protocol info and builds and sends an appropriate ack for what we can do */ -void handle_send_packet(int n) +void handle_send_packet (int n) { - int length = 3; - int bytes; - - /* initialize some protocol parameters */ - his_eol = END_CHAR; /* default end of line character */ - his_pad_count = 0; - his_pad_char = '\0'; - his_quote = K_ESCAPE; - - /* ignore last character if it filled the buffer */ - if (send_ptr == &send_parms[SEND_DATA_SIZE - 1]) --send_ptr; - bytes = send_ptr - send_parms; /* how many bytes we'll process */ - do - { - if (bytes-- <= 0) break; - /* handle MAXL - max length */ - /* ignore what he says - most I'll take (here) is 94 */ - a_b[++length] = tochar(94); - if (bytes-- <= 0) break; - /* handle TIME - time you should wait for my packets */ - /* ignore what he says - don't wait for my ack longer than 1 second */ - a_b[++length] = tochar(1); - if (bytes-- <= 0) break; - /* handle NPAD - number of pad chars I need */ - /* remember what he says - I need none */ - his_pad_count = untochar(send_parms[2]); - a_b[++length] = tochar(0); - if (bytes-- <= 0) break; - /* handle PADC - pad chars I need */ - /* remember what he says - I need none */ - his_pad_char = ktrans(send_parms[3]); - a_b[++length] = 0x40; /* He should ignore this */ - if (bytes-- <= 0) break; - /* handle EOL - end of line he needs */ - /* remember what he says - I need CR */ - his_eol = untochar(send_parms[4]); - a_b[++length] = tochar(END_CHAR); - if (bytes-- <= 0) break; - /* handle QCTL - quote control char he'll use */ - /* remember what he says - I'll use '#' */ - his_quote = send_parms[5]; - a_b[++length] = '#'; - if (bytes-- <= 0) break; - /* handle QBIN - 8-th bit prefixing */ - /* ignore what he says - I refuse */ - a_b[++length] = 'N'; - if (bytes-- <= 0) break; - /* handle CHKT - the clock check type */ - /* ignore what he says - I do type 1 (for now) */ - a_b[++length] = '1'; - if (bytes-- <= 0) break; - /* handle REPT - the repeat prefix */ - /* ignore what he says - I refuse (for now) */ - a_b[++length] = 'N'; - if (bytes-- <= 0) break; - /* handle CAPAS - the capabilities mask */ - /* ignore what he says - I only do long packets - I don't do windows */ - a_b[++length] = tochar(2); /* only long packets */ - a_b[++length] = tochar(0); /* no windows */ - a_b[++length] = tochar(94); /* large packet msb */ - a_b[++length] = tochar(94); /* large packet lsb */ - } while (0); - - a_b[0] = START_CHAR; - a_b[1] = tochar(length); - a_b[2] = tochar(n); - a_b[3] = ACK_TYPE; - a_b[++length] = '\0'; - a_b[length] = tochar(chk1(&a_b[1])); - a_b[++length] = his_eol; - a_b[++length] = '\0'; - s1_sendpacket(a_b); + int length = 3; + int bytes; + + /* initialize some protocol parameters */ + his_eol = END_CHAR; /* default end of line character */ + his_pad_count = 0; + his_pad_char = '\0'; + his_quote = K_ESCAPE; + + /* ignore last character if it filled the buffer */ + if (send_ptr == &send_parms[SEND_DATA_SIZE - 1]) + --send_ptr; + bytes = send_ptr - send_parms; /* how many bytes we'll process */ + do { + if (bytes-- <= 0) + break; + /* handle MAXL - max length */ + /* ignore what he says - most I'll take (here) is 94 */ + a_b[++length] = tochar (94); + if (bytes-- <= 0) + break; + /* handle TIME - time you should wait for my packets */ + /* ignore what he says - don't wait for my ack longer than 1 second */ + a_b[++length] = tochar (1); + if (bytes-- <= 0) + break; + /* handle NPAD - number of pad chars I need */ + /* remember what he says - I need none */ + his_pad_count = untochar (send_parms[2]); + a_b[++length] = tochar (0); + if (bytes-- <= 0) + break; + /* handle PADC - pad chars I need */ + /* remember what he says - I need none */ + his_pad_char = ktrans (send_parms[3]); + a_b[++length] = 0x40; /* He should ignore this */ + if (bytes-- <= 0) + break; + /* handle EOL - end of line he needs */ + /* remember what he says - I need CR */ + his_eol = untochar (send_parms[4]); + a_b[++length] = tochar (END_CHAR); + if (bytes-- <= 0) + break; + /* handle QCTL - quote control char he'll use */ + /* remember what he says - I'll use '#' */ + his_quote = send_parms[5]; + a_b[++length] = '#'; + if (bytes-- <= 0) + break; + /* handle QBIN - 8-th bit prefixing */ + /* ignore what he says - I refuse */ + a_b[++length] = 'N'; + if (bytes-- <= 0) + break; + /* handle CHKT - the clock check type */ + /* ignore what he says - I do type 1 (for now) */ + a_b[++length] = '1'; + if (bytes-- <= 0) + break; + /* handle REPT - the repeat prefix */ + /* ignore what he says - I refuse (for now) */ + a_b[++length] = 'N'; + if (bytes-- <= 0) + break; + /* handle CAPAS - the capabilities mask */ + /* ignore what he says - I only do long packets - I don't do windows */ + a_b[++length] = tochar (2); /* only long packets */ + a_b[++length] = tochar (0); /* no windows */ + a_b[++length] = tochar (94); /* large packet msb */ + a_b[++length] = tochar (94); /* large packet lsb */ + } while (0); + + a_b[0] = START_CHAR; + a_b[1] = tochar (length); + a_b[2] = tochar (n); + a_b[3] = ACK_TYPE; + a_b[++length] = '\0'; + a_b[length] = tochar (chk1 (&a_b[1])); + a_b[++length] = his_eol; + a_b[++length] = '\0'; + s1_sendpacket (a_b); } /* k_recv receives a OS Open image file over kermit line */ -int k_recv(void) +int k_recv (void) { - char new_char; - char k_state, k_state_saved; - int sum; - int done; - int length; - int n, last_n; - int z = 0; - int len_lo, len_hi; - - /* initialize some protocol parameters */ - his_eol = END_CHAR; /* default end of line character */ - his_pad_count = 0; - his_pad_char = '\0'; - his_quote = K_ESCAPE; - - /* initialize the k_recv and k_data state machine */ - done = 0; - k_state = 0; - k_data_init(); - k_state_saved = k_state; - k_data_save(); - n = 0; /* just to get rid of a warning */ - last_n = -1; - - /* expect this "type" sequence (but don't check): - S: send initiate - F: file header - D: data (multiple) - Z: end of file - B: break transmission - */ - - /* enter main loop */ - while (!done) - { - /* set the send packet pointer to begining of send packet parms */ - send_ptr = send_parms; - - /* With each packet, start summing the bytes starting with the length. - Save the current sequence number. - Note the type of the packet. - If a character less than SPACE (0x20) is received - error. - */ + char new_char; + char k_state, k_state_saved; + int sum; + int done; + int length; + int n, last_n; + int z = 0; + int len_lo, len_hi; + + /* initialize some protocol parameters */ + his_eol = END_CHAR; /* default end of line character */ + his_pad_count = 0; + his_pad_char = '\0'; + his_quote = K_ESCAPE; + + /* initialize the k_recv and k_data state machine */ + done = 0; + k_state = 0; + k_data_init (); + k_state_saved = k_state; + k_data_save (); + n = 0; /* just to get rid of a warning */ + last_n = -1; + + /* expect this "type" sequence (but don't check): + S: send initiate + F: file header + D: data (multiple) + Z: end of file + B: break transmission + */ + + /* enter main loop */ + while (!done) { + /* set the send packet pointer to begining of send packet parms */ + send_ptr = send_parms; + + /* With each packet, start summing the bytes starting with the length. + Save the current sequence number. + Note the type of the packet. + If a character less than SPACE (0x20) is received - error. + */ #if 0 - /* OLD CODE, Prior to checking sequence numbers */ - /* first have all state machines save current states */ - k_state_saved = k_state; - k_data_save(); + /* OLD CODE, Prior to checking sequence numbers */ + /* first have all state machines save current states */ + k_state_saved = k_state; + k_data_save (); #endif - /* get a packet */ - /* wait for the starting character */ - while (serial_getc() != START_CHAR); - /* get length of packet */ - sum = 0; - new_char = serial_getc(); - if ((new_char & 0xE0) == 0) goto packet_error; - sum += new_char & 0xff; - length = untochar(new_char); - /* get sequence number */ - new_char = serial_getc(); - if ((new_char & 0xE0) == 0) goto packet_error; - sum += new_char & 0xff; - n = untochar(new_char); - --length; - - /* NEW CODE - check sequence numbers for retried packets */ - /* Note - this new code assumes that the sequence number is correctly - received. Handling an invalid sequence number adds another layer - of complexity that may not be needed - yet! At this time, I'm hoping - that I don't need to buffer the incoming data packets and can write - the data into memory in real time. */ - if (n == last_n) - { - /* same sequence number, restore the previous state */ - k_state = k_state_saved; - k_data_restore(); - } - else - { - /* new sequence number, checkpoint the download */ - last_n = n; - k_state_saved = k_state; - k_data_save(); - } - /* END NEW CODE */ - - /* get packet type */ - new_char = serial_getc(); - if ((new_char & 0xE0) == 0) goto packet_error; - sum += new_char & 0xff; - k_state = new_char; - --length; - /* check for extended length */ - if (length == -2) - { - /* (length byte was 0, decremented twice) */ - /* get the two length bytes */ - new_char = serial_getc(); - if ((new_char & 0xE0) == 0) goto packet_error; - sum += new_char & 0xff; - len_hi = untochar(new_char); - new_char = serial_getc(); - if ((new_char & 0xE0) == 0) goto packet_error; - sum += new_char & 0xff; - len_lo = untochar(new_char); - length = len_hi * 95 + len_lo; - /* check header checksum */ - new_char = serial_getc(); - if ((new_char & 0xE0) == 0) goto packet_error; - if (new_char != tochar((sum + ((sum >> 6) & 0x03)) & 0x3f)) - goto packet_error; - sum += new_char & 0xff; - /* --length; *//* new length includes only data and block check to come */ - } - /* bring in rest of packet */ - while (length > 1) - { - new_char = serial_getc(); - if ((new_char & 0xE0) == 0) goto packet_error; - sum += new_char & 0xff; - --length; - if (k_state == DATA_TYPE) - { - /* pass on the data if this is a data packet */ - k_data_char(new_char); - } - else if (k_state == SEND_TYPE) - { - /* save send pack in buffer as is */ - *send_ptr++ = new_char; - /* if too much data, back off the pointer */ - if (send_ptr >= &send_parms[SEND_DATA_SIZE]) --send_ptr; - } - } - /* get and validate checksum character */ - new_char = serial_getc(); - if ((new_char & 0xE0) == 0) goto packet_error; - if (new_char != tochar((sum + ((sum >> 6) & 0x03)) & 0x3f)) - goto packet_error; - /* get END_CHAR */ - new_char = serial_getc(); - if (new_char != END_CHAR) - { -packet_error: - /* restore state machines */ - k_state = k_state_saved; - k_data_restore(); - /* send a negative acknowledge packet in */ - send_nack(n); - } - else if (k_state == SEND_TYPE) - { - /* crack the protocol parms, build an appropriate ack packet */ - handle_send_packet(n); - } - else - { - /* send simple acknowledge packet in */ - send_ack(n); - /* quit if end of transmission */ - if (k_state == BREAK_TYPE) done = 1; - } - ++z; - } - return 0; + /* get a packet */ + /* wait for the starting character */ + while (serial_getc () != START_CHAR); + /* get length of packet */ + sum = 0; + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + length = untochar (new_char); + /* get sequence number */ + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + n = untochar (new_char); + --length; + + /* NEW CODE - check sequence numbers for retried packets */ + /* Note - this new code assumes that the sequence number is correctly + * received. Handling an invalid sequence number adds another layer + * of complexity that may not be needed - yet! At this time, I'm hoping + * that I don't need to buffer the incoming data packets and can write + * the data into memory in real time. + */ + if (n == last_n) { + /* same sequence number, restore the previous state */ + k_state = k_state_saved; + k_data_restore (); + } else { + /* new sequence number, checkpoint the download */ + last_n = n; + k_state_saved = k_state; + k_data_save (); + } + /* END NEW CODE */ + + /* get packet type */ + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + k_state = new_char; + --length; + /* check for extended length */ + if (length == -2) { + /* (length byte was 0, decremented twice) */ + /* get the two length bytes */ + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + len_hi = untochar (new_char); + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + len_lo = untochar (new_char); + length = len_hi * 95 + len_lo; + /* check header checksum */ + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + if (new_char != tochar ((sum + ((sum >> 6) & 0x03)) & 0x3f)) + goto packet_error; + sum += new_char & 0xff; +/* --length; *//* new length includes only data and block check to come */ + } + /* bring in rest of packet */ + while (length > 1) { + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + --length; + if (k_state == DATA_TYPE) { + /* pass on the data if this is a data packet */ + k_data_char (new_char); + } else if (k_state == SEND_TYPE) { + /* save send pack in buffer as is */ + *send_ptr++ = new_char; + /* if too much data, back off the pointer */ + if (send_ptr >= &send_parms[SEND_DATA_SIZE]) + --send_ptr; + } + } + /* get and validate checksum character */ + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + if (new_char != tochar ((sum + ((sum >> 6) & 0x03)) & 0x3f)) + goto packet_error; + /* get END_CHAR */ + new_char = serial_getc (); + if (new_char != END_CHAR) { + packet_error: + /* restore state machines */ + k_state = k_state_saved; + k_data_restore (); + /* send a negative acknowledge packet in */ + send_nack (n); + } else if (k_state == SEND_TYPE) { + /* crack the protocol parms, build an appropriate ack packet */ + handle_send_packet (n); + } else { + /* send simple acknowledge packet in */ + send_ack (n); + /* quit if end of transmission */ + if (k_state == BREAK_TYPE) + done = 1; + } + ++z; + } + return ((ulong) os_data_addr - (ulong) bin_start_address); } - #endif /* CFG_CMD_LOADB */ diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 4bc4f1d..7cc000e 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -206,11 +206,10 @@ int do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) switch (hdr->ih_type) { case IH_TYPE_STANDALONE: appl = (int (*)(cmd_tbl_t *, bd_t *, int, int, char *[]))hdr->ih_ep; - - (*appl)(cmdtp, bd, flag, argc-1, &argv[1]); - /* just in case we return */ if (iflag) enable_interrupts(); + + (*appl)(cmdtp, bd, flag, argc-1, &argv[1]); break; case IH_TYPE_KERNEL: case IH_TYPE_MULTI: diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 3f56206..c1885c5 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -705,6 +705,8 @@ int do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) return 1; } printf("OK %ld Bytes loaded.\n",imsize); + + flush_cache (addr, imsize); /* Loading ok, update default load address */ load_addr = addr; diff --git a/common/cmd_ide.c b/common/cmd_ide.c index a29d7f6..9097614 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -285,6 +285,9 @@ int do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) n = ide_dev_desc[curr_device].block_read (curr_device, blk, cnt, (ulong *)addr); + /* flush cache after read */ + flush_cache (addr, cnt*ide_dev_desc[curr_device].blksz); + printf ("%ld blocks read: %s\n", n, (n==cnt) ? "OK" : "ERROR"); if (n==cnt) { diff --git a/common/cmd_net.c b/common/cmd_net.c index 64bcd8f..ac5ed27 100644 --- a/common/cmd_net.c +++ b/common/cmd_net.c @@ -101,6 +101,7 @@ netboot_common (int proto, cmd_tbl_t *cmdtp, bd_t *bd, int argc, char *argv[]) { char *s; int rcode = 0; + int size; switch (argc) { case 1: @@ -126,12 +127,15 @@ netboot_common (int proto, cmd_tbl_t *cmdtp, bd_t *bd, int argc, char *argv[]) return 1; } - if (NetLoop(bd, proto) == 0) + if ((size = NetLoop(bd, proto)) == 0) return 1; /* NetLoop ok, update environment */ netboot_update_env(); + /* flush cache */ + flush_cache(load_addr, size); + /* Loading ok, check if we should attempt an auto-start */ if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) { char *local_args[2]; diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 1235de9..b0b3f96 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -308,6 +308,9 @@ int do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } /* Loading ok, update default load address */ load_addr = addr; + + flush_cache (addr, (cnt+1)*info.blksz); + /* Check if we should attempt an auto-start */ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { char *local_args[2]; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index ce432bd..f9ab483 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -46,25 +46,25 @@ static int usb_stor_curr_dev=-1; /* current device */ char * usb_get_class_desc(unsigned char dclass) { switch(dclass) { - case USB_CLASS_PER_INTERFACE: - return("See Interface"); - case USB_CLASS_AUDIO: + case USB_CLASS_PER_INTERFACE: + return("See Interface"); + case USB_CLASS_AUDIO: return("Audio"); - case USB_CLASS_COMM: + case USB_CLASS_COMM: return("Communication"); - case USB_CLASS_HID: + case USB_CLASS_HID: return("Human Interface"); - case USB_CLASS_PRINTER: + case USB_CLASS_PRINTER: return("Printer"); - case USB_CLASS_MASS_STORAGE: + case USB_CLASS_MASS_STORAGE: return("Mass Storage"); - case USB_CLASS_HUB: + case USB_CLASS_HUB: return("Hub"); - case USB_CLASS_DATA: + case USB_CLASS_DATA: return("CDC Data"); - case USB_CLASS_VENDOR_SPEC: + case USB_CLASS_VENDOR_SPEC: return("Vendor specific"); - default : + default : return(""); } } @@ -72,9 +72,9 @@ char * usb_get_class_desc(unsigned char dclass) void usb_display_class_sub(unsigned char dclass,unsigned char subclass,unsigned char proto) { switch(dclass) { - case USB_CLASS_PER_INTERFACE: + case USB_CLASS_PER_INTERFACE: printf("See Interface"); - break; + break; case USB_CLASS_HID: printf("Human Interface, Subclass: "); switch(subclass) { @@ -149,20 +149,20 @@ void usb_display_class_sub(unsigned char dclass,unsigned char subclass,unsigned void usb_display_string(struct usb_device *dev,int index) { char buffer[256]; - if(index!=0) { - if(usb_string(dev,index,&buffer[0],256)>0); + if (index!=0) { + if (usb_string(dev,index,&buffer[0],256)>0); printf("String: \"%s\"",buffer); } } void usb_display_desc(struct usb_device *dev) { - if(dev->descriptor.bDescriptorType==USB_DT_DEVICE) { + if (dev->descriptor.bDescriptorType==USB_DT_DEVICE) { printf("%d: %s, USB Revision %x.%x\n",dev->devnum,usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass), (dev->descriptor.bcdUSB>>8) & 0xff,dev->descriptor.bcdUSB & 0xff); - if(strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial)) + if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial)) printf(" - %s %s %s\n",dev->mf,dev->prod,dev->serial); - if(dev->descriptor.bDeviceClass) { + if (dev->descriptor.bDeviceClass) { printf(" - Class: "); usb_display_class_sub(dev->descriptor.bDeviceClass,dev->descriptor.bDeviceSubClass,dev->descriptor.bDeviceProtocol); printf("\n"); @@ -170,10 +170,10 @@ void usb_display_desc(struct usb_device *dev) else { printf(" - Class: (from Interface) %s\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass)); } - printf(" - PacketSize: %d Configurations: %d\n",dev->descriptor.bMaxPacketSize0,dev->descriptor.bNumConfigurations); + printf(" - PacketSize: %d Configurations: %d\n",dev->descriptor.bMaxPacketSize0,dev->descriptor.bNumConfigurations); printf(" - Vendor: 0x%04x Product 0x%04x Version %d.%d\n",dev->descriptor.idVendor,dev->descriptor.idProduct,(dev->descriptor.bcdDevice>>8) & 0xff,dev->descriptor.bcdDevice & 0xff); } - + } void usb_display_conf_desc(struct usb_config_descriptor *config,struct usb_device *dev) @@ -181,7 +181,7 @@ void usb_display_conf_desc(struct usb_config_descriptor *config,struct usb_devic printf(" Configuration: %d\n",config->bConfigurationValue); printf(" - Interfaces: %d %s%s%dmA\n",config->bNumInterfaces,(config->bmAttributes & 0x40) ? "Self Powered " : "Bus Powered ", (config->bmAttributes & 0x20) ? "Remote Wakeup " : "",config->MaxPower*2); - if(config->iConfiguration) { + if (config->iConfiguration) { printf(" - "); usb_display_string(dev,config->iConfiguration); printf("\n"); @@ -195,7 +195,7 @@ void usb_display_if_desc(struct usb_interface_descriptor *ifdesc,struct usb_devi printf(" - Class "); usb_display_class_sub(ifdesc->bInterfaceClass,ifdesc->bInterfaceSubClass,ifdesc->bInterfaceProtocol); printf("\n"); - if(ifdesc->iInterface) { + if (ifdesc->iInterface) { printf(" - "); usb_display_string(dev,ifdesc->iInterface); printf("\n"); @@ -213,7 +213,7 @@ void usb_display_ep_desc(struct usb_endpoint_descriptor *epdesc) case 3: printf("Interrupt"); break; } printf(" MaxPacket %d",epdesc->wMaxPacketSize); - if((epdesc->bmAttributes & 0x03)==0x3) + if ((epdesc->bmAttributes & 0x03)==0x3) printf(" Interval %dms",epdesc->bInterval); printf("\n"); } @@ -244,25 +244,25 @@ void usb_show_tree_graph(struct usb_device *dev,char *pre) { int i,index; int has_child,last_child,port; - + index=strlen(pre); printf(" %s",pre); /* check if the device has connected children */ has_child=0; for(i=0;imaxchild;i++) { - if(dev->children[i]!=NULL) + if (dev->children[i]!=NULL) has_child=1; } /* check if we are the last one */ last_child=1; - if(dev->parent!=NULL) { + if (dev->parent!=NULL) { for(i=0;iparent->maxchild;i++) { /* search for children */ - if(dev->parent->children[i]==dev) { + if (dev->parent->children[i]==dev) { /* found our pointer, see if we have a little sister */ port=i; while(i++parent->maxchild) { - if(dev->parent->children[i]!=NULL) { + if (dev->parent->children[i]!=NULL) { /* found a sister */ last_child=0; break; @@ -272,7 +272,7 @@ void usb_show_tree_graph(struct usb_device *dev,char *pre) } /* for all children of the parent */ printf("\b+-"); /* correct last child */ - if(last_child) { + if (last_child) { pre[index-1]=' '; } } /* if not root hub */ @@ -284,29 +284,29 @@ void usb_show_tree_graph(struct usb_device *dev,char *pre) pre[index]=0; printf(" %s (%s, %dmA)\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass), dev->slow ? "1.5MBit/s" : "12MBit/s",dev->config.MaxPower * 2); - if(strlen(dev->mf) || + if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial)) printf(" %s %s %s %s\n",pre,dev->mf,dev->prod,dev->serial); printf(" %s\n",pre); - if(dev->maxchild>0) { + if (dev->maxchild>0) { for(i=0;imaxchild;i++) { - if(dev->children[i]!=NULL) { + if (dev->children[i]!=NULL) { usb_show_tree_graph(dev->children[i],pre); pre[index]=0; } } } -} +} /* main routine for the tree command */ void usb_show_tree(struct usb_device *dev) { char preamble[32]; - + memset(preamble,0,32); usb_show_tree_graph(dev,&preamble[0]); -} +} @@ -355,7 +355,7 @@ int do_usbboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("\n** Device %d not available\n", dev); return 1; } - if(stor_dev->block_read==NULL) { + if (stor_dev->block_read==NULL) { printf("storage device not initialized. Use usb scan\n"); return 1; } @@ -366,7 +366,7 @@ int do_usbboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } part = simple_strtoul(++ep, NULL, 16); } - + if (get_partition_info (stor_dev, part, &info)) { /* try to boot raw .... */ strncpy(&info.type[0], BOOT_PART_TYPE, sizeof(BOOT_PART_TYPE)); @@ -414,6 +414,9 @@ int do_usbboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } /* Loading ok, update default load address */ load_addr = addr; + + flush_cache (addr, (cnt+1)*info.blksz); + /* Check if we should attempt an auto-start */ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { char *local_args[2]; @@ -430,13 +433,12 @@ int do_usbboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) - /********************************************************************************* * usb command intepreter */ int do_usb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { - + int i; struct usb_device *dev; block_dev_desc_t *stor_dev; @@ -446,12 +448,12 @@ int do_usb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) usb_stop(); printf("(Re)start USB...\n"); usb_init(); - return 0; - } + return 0; + } if (strncmp(argv[1],"stop",4) == 0) { -#ifdef CONFIG_USB_KEYBOARD - if(argc==2) { - if(usb_kbd_deregister()!=0) { +#ifdef CONFIG_USB_KEYBOARD + if (argc==2) { + if (usb_kbd_deregister()!=0) { printf("USB not stopped: usbkbd still using USB\n"); return 1; } @@ -464,18 +466,18 @@ int do_usb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf("stopping USB..\n"); usb_stop(); return 0; - } + } if (strncmp(argv[1],"tree",4) == 0) { printf("\nDevice Tree:\n"); - usb_show_tree(usb_get_dev_index(0)); + usb_show_tree(usb_get_dev_index(0)); return 0; } if (strncmp(argv[1],"inf",3) == 0) { int d; - if(argc==2) { + if (argc==2) { for(d=0;ddevnum==i) + if (dev->devnum==i) break; } - if(dev==NULL) { + if (dev==NULL) { printf("*** NO Device avaiable ***\n"); return 0; } @@ -509,12 +511,12 @@ int do_usb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (strncmp(argv[1],"scan",4) == 0) { printf("Scan for storage device:\n"); usb_stor_curr_dev=usb_stor_scan(1); - if(usb_stor_curr_dev==-1) { + if (usb_stor_curr_dev==-1) { printf("No device found. Not initialized?\n"); return 1; } return 0; - } + } if (strncmp(argv[1],"part",4) == 0) { int devno, ok; for (ok=0, devno=0; devnoblock_read(usb_stor_curr_dev, blk, cnt, (ulong *)addr); printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR"); - if(n==cnt) + if (n==cnt) return 0; return 1; } } if (strcmp(argv[1],"dev") == 0) { - if(argc==3) { + if (argc==3) { int dev = (int)simple_strtoul(argv[2], NULL, 10); printf ("\nUSB device %d: ", dev); if (dev >= USB_MAX_STOR_DEV) { @@ -564,7 +566,7 @@ int do_usb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("\n Device %d: ", dev); stor_dev=usb_stor_get_dev(dev); dev_print(stor_dev); - if(stor_dev->type == DEV_TYPE_UNKNOWN) { + if (stor_dev->type == DEV_TYPE_UNKNOWN) { return 1; } usb_stor_curr_dev = dev; @@ -575,7 +577,7 @@ int do_usb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("\nUSB device %d: ", usb_stor_curr_dev); stor_dev=usb_stor_get_dev(usb_stor_curr_dev); dev_print(stor_dev); - if(stor_dev->type == DEV_TYPE_UNKNOWN) { + if (stor_dev->type == DEV_TYPE_UNKNOWN) { return 1; } return 0; diff --git a/include/ppcboot.h b/include/ppcboot.h index e296ee8..3eb07c6 100644 --- a/include/ppcboot.h +++ b/include/ppcboot.h @@ -460,6 +460,9 @@ int disable_interrupts (void); ulong lcd_setmem (ulong); #endif /* CONFIG_LCD */ +/* ppc/cache.c */ +void flush_cache (unsigned long, unsigned long); + /* ppc/ticks.S */ unsigned long long get_ticks(void); void wait_ticks (unsigned long); diff --git a/net/net.c b/net/net.c index 2de7de8..15202c8 100644 --- a/net/net.c +++ b/net/net.c @@ -247,7 +247,7 @@ restart: setenv("filesize", buf); } eth_halt(); - return 1; + return NetBootFileXferSize; case NETLOOP_FAIL: return 0; diff --git a/ppc/Makefile b/ppc/Makefile index 0235dd2..537fa15 100644 --- a/ppc/Makefile +++ b/ppc/Makefile @@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk LIB = lib$(ARCH).a AOBJS = ppcstring.o ticks.o -COBJS = ctype.o vsprintf.o extable.o string.o time.o \ +COBJS = cache.o ctype.o vsprintf.o extable.o string.o time.o \ display_options.o zlib.o crc32.o kgdb.o ldiv.o OBJS = $(AOBJS) $(COBJS) diff --git a/ppc/cache.c b/ppc/cache.c new file mode 100644 index 0000000..a6ae9cc --- /dev/null +++ b/ppc/cache.c @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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 + */ + +#include + +void flush_cache (ulong start_addr, ulong size) +{ + ulong addr, end_addr = start_addr + size; + + if (CFG_CACHELINE_SIZE) { + addr = start_addr & (CFG_CACHELINE_SIZE - 1); + for (addr = start_addr; + addr < end_addr; + addr += CFG_CACHELINE_SIZE) { + asm ("dcbst 0,%0": :"r" (addr)); + } + asm ("sync"); /* Wait for all dcbst to complete on bus */ + + for (addr = start_addr; + addr < end_addr; + addr += CFG_CACHELINE_SIZE) { + asm ("icbi 0,%0": :"r" (addr)); + } + } + asm ("sync"); /* Always flush prefetch queue in any case */ + asm ("isync"); +}