sim.c 3.9 KB

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