25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: machine.c,v 1.671 2006/06/16 18:31:24 debug Exp $ |
* $Id: machine.c,v 1.673 2006/06/24 19:52:27 debug Exp $ |
29 |
*/ |
*/ |
30 |
|
|
31 |
#include <stdio.h> |
#include <stdio.h> |
44 |
#include "bus_isa.h" |
#include "bus_isa.h" |
45 |
#include "bus_pci.h" |
#include "bus_pci.h" |
46 |
#include "cpu.h" |
#include "cpu.h" |
47 |
|
#include "debugger.h" |
48 |
#include "device.h" |
#include "device.h" |
49 |
#include "devices.h" |
#include "devices.h" |
50 |
#include "diskimage.h" |
#include "diskimage.h" |
897 |
} |
} |
898 |
|
|
899 |
|
|
900 |
|
/*****************************************************************************/ |
901 |
|
|
902 |
|
|
903 |
|
/* |
904 |
|
* machine_run(): |
905 |
|
* |
906 |
|
* Run one or more instructions on all CPUs in this machine. (Usually, |
907 |
|
* around N_SAFE_DYNTRANS_LIMIT instructions will be run by the dyntrans |
908 |
|
* system.) |
909 |
|
* |
910 |
|
* Return value is 1 if any CPU in this machine is still running, |
911 |
|
* or 0 if all CPUs are stopped. |
912 |
|
*/ |
913 |
|
int machine_run(struct machine *machine) |
914 |
|
{ |
915 |
|
struct cpu **cpus = machine->cpus; |
916 |
|
int ncpus = machine->ncpus, cpu0instrs = 0, i, te; |
917 |
|
|
918 |
|
for (i=0; i<ncpus; i++) { |
919 |
|
if (cpus[i]->running) { |
920 |
|
int instrs_run = machine->cpu_family->run_instr( |
921 |
|
machine->emul, cpus[i]); |
922 |
|
if (i == 0) |
923 |
|
cpu0instrs += instrs_run; |
924 |
|
} |
925 |
|
} |
926 |
|
|
927 |
|
/* |
928 |
|
* Hardware 'ticks': (clocks, interrupt sources...) |
929 |
|
* |
930 |
|
* Here, cpu0instrs is the number of instructions |
931 |
|
* executed on cpu0. (TODO: don't use cpu 0 for this, |
932 |
|
* use some kind of "mainbus" instead.) |
933 |
|
*/ |
934 |
|
|
935 |
|
machine->ncycles += cpu0instrs; |
936 |
|
|
937 |
|
for (te=0; te<machine->n_tick_entries; te++) { |
938 |
|
machine->ticks_till_next[te] -= cpu0instrs; |
939 |
|
if (machine->ticks_till_next[te] <= 0) { |
940 |
|
while (machine->ticks_till_next[te] <= 0) { |
941 |
|
machine->ticks_till_next[te] += |
942 |
|
machine->ticks_reset_value[te]; |
943 |
|
} |
944 |
|
|
945 |
|
machine->tick_func[te](cpus[0], |
946 |
|
machine->tick_extra[te]); |
947 |
|
} |
948 |
|
} |
949 |
|
|
950 |
|
/* Is any CPU still alive? */ |
951 |
|
for (i=0; i<ncpus; i++) |
952 |
|
if (cpus[i]->running) |
953 |
|
return 1; |
954 |
|
|
955 |
|
return 0; |
956 |
|
} |
957 |
|
|
958 |
|
|
959 |
|
/*****************************************************************************/ |
960 |
|
|
961 |
|
|
962 |
/* |
/* |
963 |
* machine_entry_new(): |
* machine_entry_new(): |
964 |
* |
* |
965 |
* This function creates a new machine_entry struct, and fills it with some |
* This function creates a new machine_entry struct, and fills it with some |
966 |
* valid data; it is up to the caller to add additional data that weren't |
* valid data; it is up to the caller to add additional data that weren't |
967 |
* passed as arguments to this function. |
* passed as arguments to this function, such as alias names and machine |
968 |
|
* subtypes. |
969 |
*/ |
*/ |
970 |
struct machine_entry *machine_entry_new(const char *name, |
struct machine_entry *machine_entry_new(const char *name, int arch, |
971 |
int arch, int oldstyle_type, int n_aliases, int n_subtypes) |
int oldstyle_type) |
972 |
{ |
{ |
973 |
struct machine_entry *me; |
struct machine_entry *me; |
974 |
|
|
983 |
me->name = name; |
me->name = name; |
984 |
me->arch = arch; |
me->arch = arch; |
985 |
me->machine_type = oldstyle_type; |
me->machine_type = oldstyle_type; |
986 |
me->n_aliases = n_aliases; |
me->n_aliases = 0; |
987 |
me->aliases = malloc(sizeof(char *) * n_aliases); |
me->aliases = NULL; |
988 |
if (me->aliases == NULL) { |
me->n_subtypes = 0; |
|
fprintf(stderr, "machine_entry_new(): out of memory (2)\n"); |
|
|
exit(1); |
|
|
} |
|
|
me->n_subtypes = n_subtypes; |
|
989 |
me->setup = NULL; |
me->setup = NULL; |
990 |
|
|
991 |
if (n_subtypes > 0) { |
return me; |
992 |
me->subtype = malloc(sizeof(struct machine_entry_subtype *) * |
} |
993 |
n_subtypes); |
|
994 |
if (me->subtype == NULL) { |
|
995 |
fprintf(stderr, "machine_entry_new(): out of " |
/* |
996 |
"memory (3)\n"); |
* machine_entry_add_alias(): |
997 |
exit(1); |
* |
998 |
} |
* This function adds an "alias" to a machine entry. |
999 |
|
*/ |
1000 |
|
void machine_entry_add_alias(struct machine_entry *me, const char *name) |
1001 |
|
{ |
1002 |
|
me->n_aliases ++; |
1003 |
|
me->aliases = realloc(me->aliases, sizeof(char *) * me->n_aliases); |
1004 |
|
if (me->aliases == NULL) { |
1005 |
|
fprintf(stderr, "out of memory\n"); |
1006 |
|
exit(1); |
1007 |
} |
} |
1008 |
|
|
1009 |
return me; |
me->aliases[me->n_aliases - 1] = (char *) name; |
1010 |
} |
} |
1011 |
|
|
1012 |
|
|
1013 |
/* |
/* |
1014 |
* machine_entry_subtype_new(): |
* machine_entry_add_subtype(): |
1015 |
* |
* |
1016 |
* This function creates a new machine_entry_subtype struct, and fills it with |
* This function adds a subtype to a machine entry. The argument list after |
1017 |
* some valid data; it is up to the caller to add additional data that weren't |
* oldstyle_subtype is a list of one or more char *, followed by NULL. E.g.: |
|
* passed as arguments to this function. |
|
1018 |
* |
* |
1019 |
* For internal use. |
* machine_entry_add_subtype(me, "Machine X", MACHINE_X, |
1020 |
|
* "machine-x", "x", NULL); |
1021 |
*/ |
*/ |
1022 |
struct machine_entry_subtype *machine_entry_subtype_new( |
void machine_entry_add_subtype(struct machine_entry *me, const char *name, |
1023 |
const char *name, int oldstyle_type, int n_aliases) |
int oldstyle_subtype, ...) |
1024 |
{ |
{ |
1025 |
|
va_list argp; |
1026 |
struct machine_entry_subtype *mes; |
struct machine_entry_subtype *mes; |
1027 |
|
|
1028 |
|
/* Allocate a new subtype struct: */ |
1029 |
mes = malloc(sizeof(struct machine_entry_subtype)); |
mes = malloc(sizeof(struct machine_entry_subtype)); |
1030 |
if (mes == NULL) { |
if (mes == NULL) { |
1031 |
fprintf(stderr, "machine_entry_subtype_new(): out " |
fprintf(stderr, "machine_entry_subtype_new(): out " |
1033 |
exit(1); |
exit(1); |
1034 |
} |
} |
1035 |
|
|
1036 |
|
/* Add the subtype to the machine entry: */ |
1037 |
|
me->n_subtypes ++; |
1038 |
|
me->subtype = realloc(me->subtype, sizeof(struct |
1039 |
|
machine_entry_subtype *) * me->n_subtypes); |
1040 |
|
if (me->subtype == NULL) { |
1041 |
|
fprintf(stderr, "out of memory\n"); |
1042 |
|
exit(1); |
1043 |
|
} |
1044 |
|
me->subtype[me->n_subtypes - 1] = mes; |
1045 |
|
|
1046 |
|
/* Fill the struct with subtype data: */ |
1047 |
memset(mes, 0, sizeof(struct machine_entry_subtype)); |
memset(mes, 0, sizeof(struct machine_entry_subtype)); |
1048 |
mes->name = name; |
mes->name = name; |
1049 |
mes->machine_subtype = oldstyle_type; |
mes->machine_subtype = oldstyle_subtype; |
1050 |
mes->n_aliases = n_aliases; |
|
1051 |
mes->aliases = malloc(sizeof(char *) * n_aliases); |
/* ... and all aliases: */ |
1052 |
if (mes->aliases == NULL) { |
mes->n_aliases = 0; |
1053 |
fprintf(stderr, "machine_entry_subtype_new(): " |
mes->aliases = NULL; |
1054 |
"out of memory (2)\n"); |
|
1055 |
exit(1); |
va_start(argp, oldstyle_subtype); |
1056 |
|
|
1057 |
|
for (;;) { |
1058 |
|
char *s = va_arg(argp, char *); |
1059 |
|
if (s == NULL) |
1060 |
|
break; |
1061 |
|
|
1062 |
|
mes->n_aliases ++; |
1063 |
|
mes->aliases = realloc(mes->aliases, sizeof(char *) * |
1064 |
|
mes->n_aliases); |
1065 |
|
if (mes->aliases == NULL) { |
1066 |
|
fprintf(stderr, "out of memory\n"); |
1067 |
|
exit(1); |
1068 |
|
} |
1069 |
|
|
1070 |
|
mes->aliases[mes->n_aliases - 1] = s; |
1071 |
} |
} |
1072 |
|
|
1073 |
return mes; |
va_end(argp); |
1074 |
} |
} |
1075 |
|
|
1076 |
|
|
1077 |
/* |
/* |
1078 |
* machine_entry_add(): |
* machine_entry_register(): |
1079 |
* |
* |
1080 |
* Inserts a new machine_entry into the machine entries list. |
* Inserts a new machine_entry into the machine entries list. |
1081 |
*/ |
*/ |
1082 |
void machine_entry_add(struct machine_entry *me, int arch) |
void machine_entry_register(struct machine_entry *me, int arch) |
1083 |
{ |
{ |
1084 |
struct machine_entry *prev, *next; |
struct machine_entry *prev, *next; |
1085 |
|
|