📄 boot.c
字号:
/* -*-C-*- * * $Revision: 1.13.6.4 $ * $Author: rivimey $ * $Date: 1998/02/11 13:15:01 $ * * Copyright (c) 1995, 1996 Advanced RISC Machines Limited. * All Rights Reserved. * * Project: ANGEL * * Title: Boot agent support for Angel. Deals with * the bootstrap related messages. */#include "angel.h" /* Generic Angel definitions. */#include "adp.h"#include "channels.h"#include "debugos.h"#include "devclnt.h" /* device control */#include "endian.h" /* Target independant endian access. */#include "params.h"#include "devdriv.h"#include "logging.h"#include "msgbuild.h"#include "support.h"#include "serlock.h"#include "banner.h" /* ANGEL_BANNER *//* called from assembler, so not in a .h file */void angel_BootInit(void);void angel_LateBootInit(unsigned int swi_code, angel_LateStartType type);/* boot_completed only TRUE once fully booted and talking to debugger */extern int boot_completed;/* cold reboot entry point */extern void __rom(void);typedef enum BootState{ BS_STARTUP, /* just started OR rebooted */ BS_AVAILABLE, /* ok for debugger to connect */ BS_RESETTING, /* reset received, awaiting TBOOT ack */ BS_CONNECTED /* connected to debugger */}BootState;/* * waiting for an ADP_Reset message; needed so channels code can take proper action * if a bad packet or heartbeat arrives. */int booted_flow_controlled = 0;#if (LATE_STARTUP > 0)static BootState boot_state = BS_STARTUP;#define REBOOT_ACK AB_LATE_ACK#elsestatic BootState boot_state = BS_AVAILABLE;#define REBOOT_ACK AB_NORMAL_ACK#endifstatic const char angel_banner[] = ANGEL_BANNER;static const unsigned int angel_banner_size = sizeof(angel_banner);static char angel_ratemsg[24];static voidsend_booted_message(){ /* Send the ADP_Booted message: */ /* NOTE: Boot-strapping is a special case, distinct from the rest of * the communications in that we may *NOT* get a reply to the * ADP_Booted message. If we transmit the message to a host that is * not yet ready, we will not get a reply. Sometime later (before * any other messages are transmitted by the host however) we should * receive an ADP_Reboot or ADP_Reset message from the host. * * NOTE: We do not block, continually re-sending the ADP_Booted * message, until we get an ACK from the host. If we did it would * mean that application based Angel systems would not start * executing until a host is attached. This does not tie cleanly * with the Angel model, of letting the application execute, with * the host being attached and removed as required. */ DeviceID device; unsigned int count, ratelen; p_Buffer buffer; LogInfo(LOG_BOOT, ( "Enter: send_booted_message\n")); buffer = angel_ChannelAllocBuffer(Angel_ChanBuffSize); if (buffer == NULL) return; ratelen = __rt_strlen(angel_ratemsg); count = msgbuild(BUFFERDATA(buffer), "%w%w%w%w%w%w%w%w%w%w%w%w", (ADP_Booted | TtoH), ADP_HandleUnknown, ADP_HandleUnknown, ADP_HandleUnknown, Angel_ChanBuffSize, /* Angel message buffer size. */ Angel_ChanLongSize, /* Angel long buffer size */ ANGELVSN, /* Angel version number. */ ADPVSN, /* ADP version number. */#if defined(THUMB_SUPPORT) && THUMB_SUPPORT!=0 ADP_ARM_ARCH_THUMB, /* ARM architecture info. */#else 0, /* ARM architecture info. */#endif angel_Endianess[0], /* CPU feature set. */ angel_Endianess[1], /* Target hardware status. */ angel_banner_size + ratelen /* No. of bytes in banner. */ ); __rt_memcpy(BUFFERDATA(buffer) + count, angel_banner, angel_banner_size); count += angel_banner_size - 1; /* banner size includes trailing null */ __rt_memcpy(BUFFERDATA(buffer) + count, angel_ratemsg, ratelen); count += ratelen; /* rate len doesn't include null */ /* ensure there is a null in there somewhere... */ (BUFFERDATA(buffer) + count)[0] = 0; count++; if (count >= Angel_ChanBuffSize) { LogWarning(LOG_BOOT, ("Boot messgage too long (%d >= %d)\n", count, Angel_ChanBuffSize)); count = Angel_ChanBuffSize; msgbuild(BUFFERDATA(buffer) + (11 * 4), "%w", count - (12*4)); } angel_ChannelReadActiveDevice(&device); booted_flow_controlled = 0; if (boot_state == BS_RESETTING) { /* * we must only accept one packet between now and the processing of the * boot ack -- the boot ack itself. If this is not enforced, there is a * race between the recieve code asking for a buffer for the next packet * and the reinitialise code which is busy clearing them. * * Sadly this has a horrible implication that we can't recover from a bad * boot ack packet or a heartbeat arriving at just the wrong time without * changes to the channels code... hence the 'booted_flow_controlled' * variable. * * The -1 in the call below says 'only let one packet through'. */ LogWarning(LOG_BOOT, ( "Restricting packet flow\n")); booted_flow_controlled = 1; angel_DeviceControl(device, DC_RX_PACKET_FLOW, (void*)-1); } /* * send the boot out and wait for a reply. */ angel_ChannelSend(device, CI_TBOOT, buffer, count); LogInfo(LOG_BOOT, ( "Leave: send_booted_message\n")); return;}static voidparam_negotiate(DeviceID devid, p_Buffer buffer){ unsigned int option[AP_NUM_PARAMS][AP_MAX_OPTIONS]; ParameterList req_list[AP_NUM_PARAMS]; ParameterOptions request; unsigned int i; LogInfo(LOG_BOOT, ( "Enter: param_negotiate\n")); /* set up empty request */ request.num_param_lists = AP_NUM_PARAMS; request.param_list = req_list; for (i = 0; i < AP_NUM_PARAMS; ++i) { request.param_list[i].num_options = AP_MAX_OPTIONS; request.param_list[i].option = option[i]; } if (Angel_ReadParamOptionsMessage(buffer, &request)) { const ParameterConfig *config; unsigned int count, speed; p_Buffer rbuff; rbuff = angel_ChannelAllocBuffer(Angel_ChanBuffSize); if (rbuff == NULL) { LogError(LOG_BOOT, ( "param_negotiate: no buffer, exit\n")); return; } count = msgbuild(rbuff, "%w%w%w%w", (ADP_ParamNegotiate | TtoH), 0, ADP_HandleUnknown, ADP_HandleUnknown); config = Angel_MatchParams(&request, &angel_Device[devid]->options); if (config != NULL) { LogInfo(LOG_BOOT, ( "param_negotiate: found param match\n")); PUT32LE(rbuff + count, RDIError_NoError); count += sizeof(word); count += Angel_BuildParamConfigMessage(rbuff + count, config); angel_ChannelSend(devid, CI_HBOOT, rbuff, count); LogInfo(LOG_BOOT, ( "param_negotiate: sent negotiate ack, setting new params\n")); /* set the new config */ angel_DeviceControl(devid, DC_SET_PARAMS, (void *)config); if (Angel_FindParam(AP_BAUD_RATE, config, &speed)) { int i; __rt_strcpy(angel_ratemsg, "Serial Rate: 0\n"); for(i = 18; i > 12 && speed != 0; i--) { angel_ratemsg[i] = (speed % 10) + '0'; speed /= 10; } } else angel_ratemsg[0] = '\0'; } else { LogWarning(LOG_BOOT, ( "param_negotiate: no param match\n")); PUT32LE(rbuff + count, RDIError_Error); count += sizeof(word); angel_ChannelSend(devid, CI_HBOOT, rbuff, count); } } else LogWarning(LOG_BOOT, ( "param_negotiate: reading param options\n")); LogInfo(LOG_BOOT, ( "param_negotiate: done.\n"));}static voidboot_handler(DeviceID devid, ChannelID chanid, p_Buffer buffer, unsigned length, void *stateptr){ unsigned int reason; unsigned int debugID; unsigned int OSinfo1; unsigned int OSinfo2; unsigned int param; IGNORE(chanid); IGNORE(stateptr); IGNORE(length); LogInfo(LOG_BOOT, ( "Enter: boot_handler\n")); unpack_message(BUFFERDATA(buffer), "%w%w%w%w%w", &reason, &debugID, &OSinfo1,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -