sim.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * arch/v850/kernel/sim.c -- Machine-specific stuff for GDB v850e simulator
  3. *
  4. * Copyright (C) 2001,02 NEC Corporation
  5. * Copyright (C) 2001,02 Miles Bader <miles@gnu.org>
  6. *
  7. * This file is subject to the terms and conditions of the GNU General
  8. * Public License. See the file COPYING in the main directory of this
  9. * archive for more details.
  10. *
  11. * Written by Miles Bader <miles@gnu.org>
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/module.h>
  15. #include <linux/init.h>
  16. #include <linux/mm.h>
  17. #include <linux/swap.h>
  18. #include <linux/bootmem.h>
  19. #include <linux/irq.h>
  20. #include <asm/atomic.h>
  21. #include <asm/page.h>
  22. #include <asm/machdep.h>
  23. #include <asm/simsyscall.h>
  24. #include "mach.h"
  25. /* The name of a file containing the root filesystem. */
  26. #define ROOT_FS "rootfs.image"
  27. extern void simcons_setup (void);
  28. extern void simcons_poll_ttys (void);
  29. extern void set_mem_root (void *addr, size_t len, char *cmd_line);
  30. static int read_file (const char *name,
  31. unsigned long *addr, unsigned long *len,
  32. const char **err);
  33. void __init mach_setup (char **cmdline)
  34. {
  35. const char *err;
  36. unsigned long root_dev_addr, root_dev_len;
  37. simcons_setup ();
  38. printk (KERN_INFO "Reading root filesystem: %s", ROOT_FS);
  39. if (read_file (ROOT_FS, &root_dev_addr, &root_dev_len, &err)) {
  40. printk (" (size %luK)\n", root_dev_len / 1024);
  41. set_mem_root ((void *)root_dev_addr, (size_t)root_dev_len,
  42. *cmdline);
  43. } else
  44. printk ("...%s failed!\n", err);
  45. }
  46. void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
  47. {
  48. *ram_start = RAM_ADDR;
  49. *ram_len = RAM_SIZE;
  50. }
  51. void __init mach_sched_init (struct irqaction *timer_action)
  52. {
  53. /* ...do magic timer initialization?... */
  54. mach_tick = simcons_poll_ttys;
  55. setup_irq (0, timer_action);
  56. }
  57. static void irq_nop (unsigned irq) { }
  58. static unsigned irq_zero (unsigned irq) { return 0; }
  59. static struct hw_interrupt_type sim_irq_type = {
  60. .typename = "IRQ",
  61. .startup = irq_zero, /* startup */
  62. .shutdown = irq_nop, /* shutdown */
  63. .enable = irq_nop, /* enable */
  64. .disable = irq_nop, /* disable */
  65. .ack = irq_nop, /* ack */
  66. .end = irq_nop, /* end */
  67. };
  68. void __init mach_init_irqs (void)
  69. {
  70. init_irq_handlers (0, NUM_MACH_IRQS, 1, &sim_irq_type);
  71. }
  72. void mach_gettimeofday (struct timespec *tv)
  73. {
  74. long timeval[2], timezone[2];
  75. int rval = V850_SIM_SYSCALL (gettimeofday, timeval, timezone);
  76. if (rval == 0) {
  77. tv->tv_sec = timeval[0];
  78. tv->tv_nsec = timeval[1] * 1000;
  79. }
  80. }
  81. void machine_restart (char *__unused)
  82. {
  83. V850_SIM_SYSCALL (write, 1, "RESTART\n", 8);
  84. V850_SIM_SYSCALL (exit, 0);
  85. }
  86. void machine_halt (void)
  87. {
  88. V850_SIM_SYSCALL (write, 1, "HALT\n", 5);
  89. V850_SIM_SYSCALL (exit, 0);
  90. }
  91. void machine_power_off (void)
  92. {
  93. V850_SIM_SYSCALL (write, 1, "POWER OFF\n", 10);
  94. V850_SIM_SYSCALL (exit, 0);
  95. }
  96. /* Load data from a file called NAME into ram. The address and length
  97. of the data image are returned in ADDR and LEN. */
  98. static int __init
  99. read_file (const char *name,
  100. unsigned long *addr, unsigned long *len,
  101. const char **err)
  102. {
  103. int rval, fd;
  104. unsigned long cur, left;
  105. /* Note this is not a normal stat buffer, it's an ad-hoc
  106. structure defined by the simulator. */
  107. unsigned long stat_buf[10];
  108. /* Stat the file to find out the length. */
  109. rval = V850_SIM_SYSCALL (stat, name, stat_buf);
  110. if (rval < 0) {
  111. if (err) *err = "stat";
  112. return 0;
  113. }
  114. *len = stat_buf[4];
  115. /* Open the file; `0' is O_RDONLY. */
  116. fd = V850_SIM_SYSCALL (open, name, 0);
  117. if (fd < 0) {
  118. if (err) *err = "open";
  119. return 0;
  120. }
  121. *addr = (unsigned long)alloc_bootmem(*len);
  122. if (! *addr) {
  123. V850_SIM_SYSCALL (close, fd);
  124. if (err) *err = "alloc_bootmem";
  125. return 0;
  126. }
  127. cur = *addr;
  128. left = *len;
  129. while (left > 0) {
  130. int chunk = V850_SIM_SYSCALL (read, fd, cur, left);
  131. if (chunk <= 0)
  132. break;
  133. cur += chunk;
  134. left -= chunk;
  135. }
  136. V850_SIM_SYSCALL (close, fd);
  137. if (left > 0) {
  138. /* Some read failed. */
  139. free_bootmem (*addr, *len);
  140. if (err) *err = "read";
  141. return 0;
  142. }
  143. return 1;
  144. }