Mercurial > ecos
comparison packages/hal/common/current/src/generic-stub.c @ 46:797268ecc331 ecos-sw-1999-10-19
Merge from eCos master repository on 1999-10-19-18:55:31-BST
| author | jlarmour |
|---|---|
| date | Tue, 19 Oct 1999 19:19:52 +0000 |
| parents | e7ba79f6d3a8 |
| children | 1370c5e55234 |
comparison
equal
deleted
inserted
replaced
| 45:91d213c0da48 | 46:797268ecc331 |
|---|---|
| 816 * FIXME: evidently I need a new hook for large registers... | 816 * FIXME: evidently I need a new hook for large registers... |
| 817 */ | 817 */ |
| 818 | 818 |
| 819 int (*_get_trace_register_hook) (regnames_t, target_register_t *); | 819 int (*_get_trace_register_hook) (regnames_t, target_register_t *); |
| 820 | 820 |
| 821 void | |
| 822 stub_format_registers(char *ptr) | |
| 823 { | |
| 824 int regnum; | |
| 825 | |
| 826 for (regnum = 0; regnum < NUMREGS_GDB; regnum++) { | |
| 827 /* We need to compensate for the value offset within the | |
| 828 register. */ | |
| 829 char dummyDat[32]; | |
| 830 target_register_t addr; | |
| 831 char *vptr; | |
| 832 int reg_valid = 1; | |
| 833 | |
| 834 #ifdef TARGET_HAS_LARGE_REGISTERS | |
| 835 if (sizeof (target_register_t) < REGSIZE (regnum)) { | |
| 836 get_register_as_bytes (regnum, dummyDat); | |
| 837 vptr = dummyDat; | |
| 838 } else | |
| 839 #endif | |
| 840 { | |
| 841 if (_get_trace_register_hook) | |
| 842 reg_valid = _get_trace_register_hook (regnum, &addr); | |
| 843 else | |
| 844 addr = get_register (regnum); | |
| 845 | |
| 846 vptr = ((char *) &addr); | |
| 847 if (sizeof (addr) > REGSIZE(regnum)) { | |
| 848 /* May need to cope with endian-ness */ | |
| 849 | |
| 850 #if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN) | |
| 851 vptr += sizeof (addr) - REGSIZE (regnum); | |
| 852 #endif | |
| 853 } else if (sizeof (addr) < REGSIZE (regnum)) { | |
| 854 int off = REGSIZE (regnum) - sizeof (addr); | |
| 855 int x; | |
| 856 | |
| 857 for (x = 0; x < off; x++) | |
| 858 dummyDat[x] = 0; | |
| 859 memcpy (dummyDat + off, &addr, sizeof (addr)); | |
| 860 vptr = dummyDat; | |
| 861 } | |
| 862 } | |
| 863 if (reg_valid) { /* we have a valid reg value */ | |
| 864 ptr = __mem2hex (vptr, ptr, REGSIZE (regnum), 0); | |
| 865 } else { | |
| 866 /* Trace component returned a failure code. | |
| 867 This means that the register value is not available. | |
| 868 We'll fill it with 'x's, and GDB will understand. */ | |
| 869 memset (ptr, 'x', 2 * REGSIZE (regnum)); | |
| 870 ptr += 2 * REGSIZE (regnum); | |
| 871 } | |
| 872 } | |
| 873 } | |
| 874 | |
| 875 void | |
| 876 stub_update_registers(char *in_ptr, char *out_ptr) | |
| 877 { | |
| 878 char *ptr = &in_ptr[1]; | |
| 879 int x; | |
| 880 int sr = 0, er = NUMREGS_GDB; | |
| 881 | |
| 882 if (*in_ptr == 'P') { | |
| 883 target_register_t regno; | |
| 884 | |
| 885 if (__hexToInt (&ptr, ®no) && (*ptr++ == '=')) { | |
| 886 | |
| 887 sr = regno; | |
| 888 er = regno + 1; | |
| 889 } else { | |
| 890 strcpy (out_ptr, "P01"); | |
| 891 return; | |
| 892 } | |
| 893 } | |
| 894 | |
| 895 for (x = sr; x < er; x++) { | |
| 896 target_register_t value = 0; | |
| 897 char *vptr; | |
| 898 | |
| 899 #ifdef TARGET_HAS_LARGE_REGISTERS | |
| 900 if (sizeof (target_register_t) < REGSIZE (x)) { | |
| 901 char dummyDat [32]; | |
| 902 | |
| 903 __hex2mem (ptr, dummyDat, REGSIZE (x), 0); | |
| 904 put_register_as_bytes (x, dummyDat); | |
| 905 } else | |
| 906 #endif | |
| 907 { | |
| 908 vptr = ((char *) &value); | |
| 909 #if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN) | |
| 910 vptr += sizeof (value) - REGSIZE (x); | |
| 911 #endif | |
| 912 __hex2mem (ptr, vptr, REGSIZE (x), 0); | |
| 913 put_register (x, value); | |
| 914 } | |
| 915 ptr += REGSIZE (x) * 2; | |
| 916 } | |
| 917 | |
| 918 strcpy (out_ptr, "OK"); | |
| 919 } | |
| 920 | |
| 821 int | 921 int |
| 822 __process_packet (char *packet) | 922 __process_packet (char *packet) |
| 823 { | 923 { |
| 824 int is_binary = 0; | 924 int is_binary = 0; |
| 825 remcomOutBuffer[0] = 0; | 925 remcomOutBuffer[0] = 0; |
| 856 break; | 956 break; |
| 857 | 957 |
| 858 case 'g': /* return the value of the CPU registers */ | 958 case 'g': /* return the value of the CPU registers */ |
| 859 { | 959 { |
| 860 char *ptr = remcomOutBuffer; | 960 char *ptr = remcomOutBuffer; |
| 861 int regnum; | 961 stub_format_registers(ptr); |
| 862 | |
| 863 for (regnum = 0; regnum < NUMREGS_GDB; regnum++) | |
| 864 { | |
| 865 /* We need to compensate for the value offset within the | |
| 866 register. */ | |
| 867 char dummyDat[32]; | |
| 868 target_register_t addr; | |
| 869 char *vptr; | |
| 870 int reg_valid = 1; | |
| 871 | |
| 872 #ifdef TARGET_HAS_LARGE_REGISTERS | |
| 873 if (sizeof (target_register_t) < REGSIZE (regnum)) | |
| 874 { | |
| 875 get_register_as_bytes (regnum, dummyDat); | |
| 876 vptr = dummyDat; | |
| 877 } | |
| 878 else | |
| 879 #endif | |
| 880 { | |
| 881 if (_get_trace_register_hook) | |
| 882 reg_valid = _get_trace_register_hook (regnum, &addr); | |
| 883 else | |
| 884 addr = get_register (regnum); | |
| 885 | |
| 886 vptr = ((char *) &addr); | |
| 887 if (sizeof (addr) > REGSIZE(regnum)) | |
| 888 { | |
| 889 /* May need to cope with endian-ness */ | |
| 890 | |
| 891 #if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN) | |
| 892 vptr += sizeof (addr) - REGSIZE (regnum); | |
| 893 #endif | |
| 894 } | |
| 895 else if (sizeof (addr) < REGSIZE (regnum)) | |
| 896 { | |
| 897 int off = REGSIZE (regnum) - sizeof (addr); | |
| 898 int x; | |
| 899 | |
| 900 for (x = 0; x < off; x++) | |
| 901 dummyDat[x] = 0; | |
| 902 memcpy (dummyDat + off, &addr, sizeof (addr)); | |
| 903 vptr = dummyDat; | |
| 904 } | |
| 905 } | |
| 906 if (reg_valid) /* we have a valid reg value */ | |
| 907 { | |
| 908 ptr = __mem2hex (vptr, ptr, REGSIZE (regnum), 0); | |
| 909 } | |
| 910 else | |
| 911 { | |
| 912 /* Trace component returned a failure code. | |
| 913 This means that the register value is not available. | |
| 914 We'll fill it with 'x's, and GDB will understand. */ | |
| 915 memset (ptr, 'x', 2 * REGSIZE (regnum)); | |
| 916 ptr += 2 * REGSIZE (regnum); | |
| 917 } | |
| 918 } | |
| 919 break; | 962 break; |
| 920 } | 963 } |
| 921 | 964 |
| 922 case 'A': /* set program arguments */ | 965 case 'A': /* set program arguments */ |
| 923 { | 966 { |
| 965 break; | 1008 break; |
| 966 | 1009 |
| 967 case 'P': | 1010 case 'P': |
| 968 case 'G': /* set the value of the CPU registers - return OK */ | 1011 case 'G': /* set the value of the CPU registers - return OK */ |
| 969 { | 1012 { |
| 970 int x; | 1013 char *in_ptr = &packet[0]; |
| 971 int sr = 0, er = NUMREGS_GDB; | 1014 char *out_ptr = remcomOutBuffer; |
| 972 char *ptr = &packet[1]; | 1015 stub_update_registers(in_ptr, out_ptr); |
| 973 | |
| 974 if (packet[0] == 'P') | |
| 975 { | |
| 976 target_register_t regno; | |
| 977 | |
| 978 if (__hexToInt (&ptr, ®no) | |
| 979 && (*ptr++ == '=')) | |
| 980 { | |
| 981 sr = regno; | |
| 982 er = regno + 1; | |
| 983 } | |
| 984 else | |
| 985 { | |
| 986 strcpy (remcomOutBuffer, "P01"); | |
| 987 break; | |
| 988 } | |
| 989 } | |
| 990 | |
| 991 for (x = sr; x < er; x++) | |
| 992 { | |
| 993 target_register_t value = 0; | |
| 994 char *vptr; | |
| 995 | |
| 996 #ifdef TARGET_HAS_LARGE_REGISTERS | |
| 997 if (sizeof (target_register_t) < REGSIZE (x)) | |
| 998 { | |
| 999 char dummyDat [32]; | |
| 1000 | |
| 1001 __hex2mem (ptr, dummyDat, REGSIZE (x), 0); | |
| 1002 put_register_as_bytes (x, dummyDat); | |
| 1003 } | |
| 1004 else | |
| 1005 #endif | |
| 1006 { | |
| 1007 vptr = ((char *) &value); | |
| 1008 #if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN) | |
| 1009 vptr += sizeof (value) - REGSIZE (x); | |
| 1010 #endif | |
| 1011 __hex2mem (ptr, vptr, REGSIZE (x), 0); | |
| 1012 put_register (x, value); | |
| 1013 } | |
| 1014 ptr += REGSIZE (x) * 2; | |
| 1015 } | |
| 1016 | |
| 1017 strcpy (remcomOutBuffer, "OK"); | |
| 1018 break; | 1016 break; |
| 1019 } | 1017 } |
| 1020 | 1018 |
| 1021 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ | 1019 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ |
| 1022 /* Try to read %x,%x. */ | 1020 /* Try to read %x,%x. */ |
