BOOK.TXT
上传用户:datang2001
上传日期:2007-02-01
资源大小:53269k
文件大小:999k
源码类别:

操作系统开发

开发平台:

C/C++

  1. 04336 #define NMI_VECTOR         2    /* non-maskable interrupt */
  2. 04337 #define BREAKPOINT_VECTOR  3    /* software breakpoint */
  3. 04338 #define OVERFLOW_VECTOR    4    /* from INTO */
  4. 04339
  5. 04340 /* Fixed system call vector. */
  6. 04341 #define SYS_VECTOR        32    /* system calls are made with int SYSVEC */
  7. 04342 #define SYS386_VECTOR     33    /* except 386 system calls use this */
  8. 04343 #define LEVEL0_VECTOR     34    /* for execution of a function at level 0 */
  9. 04344
  10. 04345 /* Suitable irq bases for hardware interrupts.  Reprogram the 8259(s) from
  11. 04346  * the PC BIOS defaults since the BIOS doesn't respect all the processor's
  12. 04347  * reserved vectors (0 to 31).
  13. 04348  */
  14. 04349 #define BIOS_IRQ0_VEC   0x08    /* base of IRQ0-7 vectors used by BIOS */
  15. 04350 #define BIOS_IRQ8_VEC   0x70    /* base of IRQ8-15 vectors used by BIOS */
  16. 04351 #define IRQ0_VECTOR     0x28    /* more or less arbitrary, but > SYS_VECTOR */
  17. 04352 #define IRQ8_VECTOR     0x30    /* together for simplicity */
  18. 04353
  19. 04354 /* Hardware interrupt numbers. */
  20. 04355 #define NR_IRQ_VECTORS    16
  21. 04356 #define CLOCK_IRQ          0
  22. 04357 #define KEYBOARD_IRQ       1
  23. 04358 #define CASCADE_IRQ        2    /* cascade enable for 2nd AT controller */
  24. 04359 #define ETHER_IRQ          3    /* default ethernet interrupt vector */
  25. 04360 #define SECONDARY_IRQ      3    /* RS232 interrupt vector for port 2 */
  26. 04361 #define RS232_IRQ          4    /* RS232 interrupt vector for port 1 */
  27. 04362 #define XT_WINI_IRQ        5    /* xt winchester */
  28. 04363 #define FLOPPY_IRQ         6    /* floppy disk */
  29. 04364 #define PRINTER_IRQ        7
  30. 04365 #define AT_WINI_IRQ       14    /* at winchester */
  31. 04366
  32. 04367 /* Interrupt number to hardware vector. */
  33. 04368 #define BIOS_VECTOR(irq)        
  34. 04369         (((irq) < 8 ? BIOS_IRQ0_VEC : BIOS_IRQ8_VEC) + ((irq) & 0x07))
  35. 04370 #define VECTOR(irq)     
  36. 04371         (((irq) < 8 ? IRQ0_VECTOR : IRQ8_VECTOR) + ((irq) & 0x07))
  37. 04372
  38. 04373 /* BIOS hard disk parameter vectors. */
  39. 04374 #define WINI_0_PARM_VEC 0x41
  40. 04375 #define WINI_1_PARM_VEC 0x46
  41. 04376
  42. 04377 /* 8259A interrupt controller ports. */
  43. 04378 #define INT_CTL         0x20    /* I/O port for interrupt controller */
  44. 04379 #define INT_CTLMASK     0x21    /* setting bits in this port disables ints */
  45. 04380 #define INT2_CTL        0xA0    /* I/O port for second interrupt controller */
  46. 04381 #define INT2_CTLMASK    0xA1    /* setting bits in this port disables ints */
  47. 04382
  48. 04383 /* Magic numbers for interrupt controller. */
  49. 04384 #define ENABLE          0x20    /* code used to re-enable after an interrupt */
  50. 04385
  51. 04386 /* Sizes of memory tables. */
  52. 04387 #define NR_MEMS            3    /* number of chunks of memory */
  53. 04388
  54. 04389 /* Miscellaneous ports. */
  55. 04390 #define PCR             0x65    /* Planar Control Register */
  56. 04391 #define PORT_B          0x61    /* I/O port for 8255 port B (kbd, beeper...) */
  57. 04392 #define TIMER0          0x40    /* I/O port for timer channel 0 */
  58. 04393 #define TIMER2          0x42    /* I/O port for timer channel 2 */
  59. 04394 #define TIMER_MODE      0x43    /* I/O port for timer mode control */
  60. 04395
  61. 04396 #endif /* (CHIP == INTEL) */
  62. 04397
  63. 04398 #if (CHIP == M68000)
  64. 04399
  65. 04400 #define K_STACK_BYTES   1024    /* how many bytes for the kernel stack */
  66. 04401
  67. 04402 /* Sizes of memory tables. */
  68. 04403 #define NR_MEMS            2    /* number of chunks of memory */
  69. 04404
  70. 04405 /* p_reg contains: d0-d7, a0-a6,   in that order. */
  71. 04406 #define NR_REGS           15    /* number of general regs in each proc slot */
  72. 04407  
  73. 04408 #define TRACEBIT      0x8000    /* or this with psw in proc[] for tracing */
  74. 04409 #define SETPSW(rp, new)         /* permits only certain bits to be set */ 
  75. 04410         ((rp)->p_reg.psw = (rp)->p_reg.psw & ~0xFF | (new) & 0xFF)
  76. 04411  
  77. 04412 #define MEM_BYTES  0xffffffff   /* memory size for /dev/mem */
  78. 04413  
  79. 04414 #ifdef __ACK__
  80. 04415 #define FSTRUCOPY
  81. 04416 #endif
  82. 04417
  83. 04418 #endif /* (CHIP == M68000) */
  84. 04419
  85. 04420 /* The following items pertain to the scheduling queues. */
  86. 04421 #define TASK_Q             0    /* ready tasks are scheduled via queue 0 */
  87. 04422 #define SERVER_Q           1    /* ready servers are scheduled via queue 1 */
  88. 04423 #define USER_Q             2    /* ready users are scheduled via queue 2 */
  89. 04424
  90. 04425 #if (MACHINE == ATARI)
  91. 04426 #define SHADOW_Q           3    /* runnable, but shadowed processes */
  92. 04427 #define NQ                 4    /* # of scheduling queues */
  93. 04428 #else
  94. 04429 #define NQ                 3    /* # of scheduling queues */
  95. 04430 #endif
  96. 04431
  97. 04432 /* Env_parse() return values. */
  98. 04433 #define EP_UNSET        0       /* variable not set */
  99. 04434 #define EP_OFF          1       /* var = off */
  100. 04435 #define EP_ON           2       /* var = on (or field left blank) */
  101. 04436 #define EP_SET          3       /* var = 1:2:3 (nonblank field) */
  102. 04437
  103. 04438 /* To translate an address in kernel space to a physical address.  This is
  104. 04439  * the same as umap(proc_ptr, D, vir, sizeof(*vir)), but a lot less costly.
  105. 04440  */
  106. 04441 #define vir2phys(vir)   (data_base + (vir_bytes) (vir))
  107. 04442
  108. 04443 #define printf        printk    /* the kernel really uses printk, not printf */
  109. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  110. src/kernel/type.h    
  111. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  112. 04500 #ifndef TYPE_H
  113. 04501 #define TYPE_H
  114. 04502
  115. 04503 typedef _PROTOTYPE( void task_t, (void) );
  116. 04504 typedef _PROTOTYPE( int (*rdwt_t), (message *m_ptr) );
  117. 04505 typedef _PROTOTYPE( void (*watchdog_t), (void) );
  118. 04506
  119. 04507 struct tasktab {
  120. 04508   task_t *initial_pc;
  121. 04509   int stksize;
  122. 04510   char name[8];
  123. 04511 };
  124. 04512
  125. 04513 struct memory {
  126. 04514   phys_clicks base;
  127. 04515   phys_clicks size;
  128. 04516 };
  129. 04517
  130. 04518 /* Administration for clock polling. */
  131. 04519 struct milli_state {
  132. 04520   unsigned long accum_count;    /* accumulated clock ticks */
  133. 04521   unsigned prev_count;          /* previous clock value */
  134. 04522 };
  135. 04523
  136. 04524 #if (CHIP == INTEL)
  137. 04525 typedef unsigned port_t;
  138. 04526 typedef unsigned segm_t;
  139. 04527 typedef unsigned reg_t;         /* machine register */
  140. 04528
  141. 04529 /* The stack frame layout is determined by the software, but for efficiency
  142. 04530  * it is laid out so the assembly code to use it is as simple as possible.
  143. 04531  * 80286 protected mode and all real modes use the same frame, built with
  144. 04532  * 16-bit registers.  Real mode lacks an automatic stack switch, so little
  145. 04533  * is lost by using the 286 frame for it.  The 386 frame differs only in
  146. 04534  * having 32-bit registers and more segment registers.  The same names are
  147. 04535  * used for the larger registers to avoid differences in the code.
  148. 04536  */
  149. 04537 struct stackframe_s {           /* proc_ptr points here */
  150. 04538 #if _WORD_SIZE == 4
  151. 04539   u16_t gs;                     /* last item pushed by save */
  152. 04540   u16_t fs;                     /*  ^ */
  153. 04541 #endif
  154. 04542   u16_t es;                     /*  | */
  155. 04543   u16_t ds;                     /*  | */
  156. 04544   reg_t di;                     /* di through cx are not accessed in C */
  157. 04545   reg_t si;                     /* order is to match pusha/popa */
  158. 04546   reg_t fp;                     /* bp */
  159. 04547   reg_t st;                     /* hole for another copy of sp */
  160. 04548   reg_t bx;                     /*  | */
  161. 04549   reg_t dx;                     /*  | */
  162. 04550   reg_t cx;                     /*  | */
  163. 04551   reg_t retreg;                 /* ax and above are all pushed by save */
  164. 04552   reg_t retadr;                 /* return address for assembly code save() */
  165. 04553   reg_t pc;                     /*  ^  last item pushed by interrupt */
  166. 04554   reg_t cs;                     /*  | */
  167. 04555   reg_t psw;                    /*  | */
  168. 04556   reg_t sp;                     /*  | */
  169. 04557   reg_t ss;                     /* these are pushed by CPU during interrupt */
  170. 04558 };
  171. 04559
  172. 04560 struct segdesc_s {              /* segment descriptor for protected mode */
  173. 04561   u16_t limit_low;
  174. 04562   u16_t base_low;
  175. 04563   u8_t base_middle;
  176. 04564   u8_t access;                  /* |P|DL|1|X|E|R|A| */
  177. 04565 #if _WORD_SIZE == 4
  178. 04566   u8_t granularity;             /* |G|X|0|A|LIMT| */
  179. 04567   u8_t base_high;
  180. 04568 #else
  181. 04569   u16_t reserved;
  182. 04570 #endif
  183. 04571 };
  184. 04572
  185. 04573 typedef _PROTOTYPE( int (*irq_handler_t), (int irq) );
  186. 04574
  187. 04575 #endif /* (CHIP == INTEL) */
  188. 04576
  189. 04577 #if (CHIP == M68000)
  190. 04578 typedef _PROTOTYPE( void (*dmaint_t), (void) );
  191. 04579
  192. 04580 typedef u32_t reg_t;            /* machine register */
  193. 04581
  194. 04582 /* The name and fields of this struct were chosen for PC compatibility. */
  195. 04583 struct stackframe_s {
  196. 04584   reg_t retreg;                 /* d0 */
  197. 04585   reg_t d1;
  198. 04586   reg_t d2;
  199. 04587   reg_t d3;
  200. 04588   reg_t d4;
  201. 04589   reg_t d5;
  202. 04590   reg_t d6;
  203. 04591   reg_t d7;
  204. 04592   reg_t a0;
  205. 04593   reg_t a1;
  206. 04594   reg_t a2;
  207. 04595   reg_t a3;
  208. 04596   reg_t a4;
  209. 04597   reg_t a5;
  210. 04598   reg_t fp;                     /* also known as a6 */
  211. 04599   reg_t sp;                     /* also known as a7 */
  212. 04600   reg_t pc;
  213. 04601   u16_t psw;
  214. 04602   u16_t dummy;                  /* make size multiple of reg_t for system.c */
  215. 04603 };
  216. 04604
  217. 04605 struct fsave {
  218. 04606   struct cpu_state {
  219. 04607         u16_t i_format;
  220. 04608         u32_t i_addr;
  221. 04609         u16_t i_state[4];
  222. 04610   } cpu_state;
  223. 04611   struct state_frame {
  224. 04612         u8_t frame_type;
  225. 04613         u8_t frame_size;
  226. 04614         u16_t reserved;
  227. 04615         u8_t frame[212];
  228. 04616   } state_frame;
  229. 04617   struct fpp_model {
  230. 04618         u32_t fpcr;
  231. 04619         u32_t fpsr;
  232. 04620         u32_t fpiar;
  233. 04621         struct fpN {
  234. 04622                 u32_t high;
  235. 04623                 u32_t low;
  236. 04624                 u32_t mid;
  237. 04625         } fpN[8];
  238. 04626   } fpp_model;
  239. 04627 };
  240. 04628 #endif /* (CHIP == M68000) */
  241. 04629
  242. 04630 #endif /* TYPE_H */
  243. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  244. src/kernel/proto.h    
  245. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  246. 04700 /* Function prototypes. */
  247. 04701
  248. 04702 #ifndef PROTO_H
  249. 04703 #define PROTO_H
  250. 04704
  251. 04705 /* Struct declarations. */
  252. 04706 struct proc;
  253. 04707 struct tty;
  254. 04708
  255. 04709 /* at_wini.c, wini.c */
  256. 04710 _PROTOTYPE( void winchester_task, (void)                                );
  257. 04711 _PROTOTYPE( void at_winchester_task, (void)                             );
  258. 04712
  259. 04713 /* clock.c */
  260. 04714 _PROTOTYPE( void clock_task, (void)                                     );
  261. 04715 _PROTOTYPE( void clock_stop, (void)                                     );
  262. 04716 _PROTOTYPE( clock_t get_uptime, (void)                                  );
  263. 04717 _PROTOTYPE( void syn_alrm_task, (void)                                  );
  264. 04718
  265. 04719 /* dmp.c */
  266. 04720 _PROTOTYPE( void map_dmp, (void)                                        );
  267. 04721 _PROTOTYPE( void p_dmp, (void)                                          );
  268. 04722 _PROTOTYPE( void reg_dmp, (struct proc *rp)                             );
  269. 04723
  270. 04724 /* dp8390.c */
  271. 04725 _PROTOTYPE( void dp8390_task, (void)                                    );
  272. 04726 _PROTOTYPE( void dp_dump, (void)                                        );
  273. 04727 _PROTOTYPE( void dp8390_stop, (void)                                    );
  274. 04728
  275. 04729 /* floppy.c, stfloppy.c */
  276. 04730 _PROTOTYPE( void floppy_task, (void)                                    );
  277. 04731 _PROTOTYPE( void floppy_stop, (void)                                    );
  278. 04732
  279. 04733 /* main.c, stmain.c */
  280. 04734 _PROTOTYPE( void main, (void)                                           );
  281. 04735 _PROTOTYPE( void panic, (const char *s, int n)                          );
  282. 04736
  283. 04737 /* memory.c */
  284. 04738 _PROTOTYPE( void mem_task, (void)                                       );
  285. 04739
  286. 04740 /* misc.c */
  287. 04741 _PROTOTYPE( int env_parse, (char *env, char *fmt, int field,
  288. 04742                         long *param, long min, long max)                );
  289. 04743
  290. 04744 /* printer.c, stprint.c */
  291. 04745 _PROTOTYPE( void printer_task, (void)                                   );
  292. 04746
  293. 04747 /* proc.c */
  294. 04748 _PROTOTYPE( void interrupt, (int task)                                  );
  295. 04749 _PROTOTYPE( int lock_mini_send, (struct proc *caller_ptr,
  296. 04750                 int dest, message *m_ptr)                               );
  297. 04751 _PROTOTYPE( void lock_pick_proc, (void)                                 );
  298. 04752 _PROTOTYPE( void lock_ready, (struct proc *rp)                          );
  299. 04753 _PROTOTYPE( void lock_sched, (void)                                     );
  300. 04754 _PROTOTYPE( void lock_unready, (struct proc *rp)                        );
  301. 04755 _PROTOTYPE( int sys_call, (int function, int src_dest, message *m_ptr)  );
  302. 04756 _PROTOTYPE( void unhold, (void)                                         );
  303. 04757
  304. 04758 /* rs232.c */
  305. 04759 _PROTOTYPE( void rs_init, (struct tty *tp)                              );
  306. 04760
  307. 04761 /* system.c */
  308. 04762 _PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr)                   );
  309. 04763 _PROTOTYPE( void inform, (void)                                         );
  310. 04764 _PROTOTYPE( phys_bytes numap, (int proc_nr, vir_bytes vir_addr, 
  311. 04765                 vir_bytes bytes)                                        );
  312. 04766 _PROTOTYPE( void sys_task, (void)                                       );
  313. 04767 _PROTOTYPE( phys_bytes umap, (struct proc *rp, int seg, vir_bytes vir_addr,
  314. 04768                 vir_bytes bytes)                                        );
  315. 04769
  316. 04770 /* tty.c */
  317. 04771 _PROTOTYPE( void handle_events, (struct tty *tp)                        );
  318. 04772 _PROTOTYPE( void sigchar, (struct tty *tp, int sig)                     );
  319. 04773 _PROTOTYPE( void tty_task, (void)                                       );
  320. 04774 _PROTOTYPE( int in_process, (struct tty *tp, char *buf, int count)      );
  321. 04775 _PROTOTYPE( void out_process, (struct tty *tp, char *bstart, char *bpos,
  322. 04776                                 char *bend, int *icount, int *ocount)   );
  323. 04777 _PROTOTYPE( void tty_wakeup, (clock_t now)                              );
  324. 04778 _PROTOTYPE( void tty_reply, (int code, int replyee, int proc_nr,
  325. 04779                                                         int status)     );
  326. 04780 _PROTOTYPE( void tty_devnop, (struct tty *tp)                           );
  327. 04781
  328. 04782 /* library */
  329. 04783 _PROTOTYPE( void *memcpy, (void *_s1, const void *_s2, size_t _n)       );
  330. 04784
  331. 04785 #if (CHIP == INTEL)
  332. 04786
  333. 04787 /* clock.c */
  334. 04788 _PROTOTYPE( void milli_start, (struct milli_state *msp)                 );
  335. 04789 _PROTOTYPE( unsigned milli_elapsed, (struct milli_state *msp)           );
  336. 04790 _PROTOTYPE( void milli_delay, (unsigned millisec)                       );
  337. 04791
  338. 04792 /* console.c */
  339. 04793 _PROTOTYPE( void cons_stop, (void)                                      );
  340. 04794 _PROTOTYPE( void putk, (int c)                                          );
  341. 04795 _PROTOTYPE( void scr_init, (struct tty *tp)                             );
  342. 04796 _PROTOTYPE( void toggle_scroll, (void)                                  );
  343. 04797 _PROTOTYPE( int con_loadfont, (phys_bytes user_phys)                    );
  344. 04798 _PROTOTYPE( void select_console, (int cons_line)                        );
  345. 04799
  346. 04800 /* cstart.c */
  347. 04801 _PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mcs, U16_t mds,
  348. 04802                                 U16_t parmoff, U16_t parmsize)          );
  349. 04803 _PROTOTYPE( char *k_getenv, (char *name)                                );
  350. 04804
  351. 04805 /* exception.c */
  352. 04806 _PROTOTYPE( void exception, (unsigned vec_nr)                           );
  353. 04807
  354. 04808 /* i8259.c */
  355. 04809 _PROTOTYPE( irq_handler_t get_irq_handler, (int irq)                    );
  356. 04810 _PROTOTYPE( void put_irq_handler, (int irq, irq_handler_t handler)      );
  357. 04811 _PROTOTYPE( void intr_init, (int mine)                                  );
  358. 04812
  359. 04813 /* keyboard.c */
  360. 04814 _PROTOTYPE( void kb_init, (struct tty *tp)                              );
  361. 04815 _PROTOTYPE( int kbd_loadmap, (phys_bytes user_phys)                     );
  362. 04816 _PROTOTYPE( void wreboot, (int how)                                     );
  363. 04817
  364. 04818 /* klib*.s */
  365. 04819 _PROTOTYPE( void bios13, (void)                                         );
  366. 04820 _PROTOTYPE( phys_bytes check_mem, (phys_bytes base, phys_bytes size)    );
  367. 04821 _PROTOTYPE( void cp_mess, (int src,phys_clicks src_clicks,vir_bytes src_offset,
  368. 04822                 phys_clicks dst_clicks, vir_bytes dst_offset)           );
  369. 04823 _PROTOTYPE( int in_byte, (port_t port)                                  );
  370. 04824 _PROTOTYPE( int in_word, (port_t port)                                  );
  371. 04825 _PROTOTYPE( void lock, (void)                                           );
  372. 04826 _PROTOTYPE( void unlock, (void)                                         );
  373. 04827 _PROTOTYPE( void enable_irq, (unsigned irq)                             );
  374. 04828 _PROTOTYPE( int disable_irq, (unsigned irq)                             );
  375. 04829 _PROTOTYPE( u16_t mem_rdw, (segm_t segm, vir_bytes offset)              );
  376. 04830 _PROTOTYPE( void out_byte, (port_t port, int value)                     );
  377. 04831 _PROTOTYPE( void out_word, (port_t port, int value)                     );
  378. 04832 _PROTOTYPE( void phys_copy, (phys_bytes source, phys_bytes dest,
  379. 04833                 phys_bytes count)                                       );
  380. 04834 _PROTOTYPE( void port_read, (unsigned port, phys_bytes destination,
  381. 04835                 unsigned bytcount)                                      );
  382. 04836 _PROTOTYPE( void port_read_byte, (unsigned port, phys_bytes destination,
  383. 04837                 unsigned bytcount)                                      );
  384. 04838 _PROTOTYPE( void port_write, (unsigned port, phys_bytes source,
  385. 04839                 unsigned bytcount)                                      );
  386. 04840 _PROTOTYPE( void port_write_byte, (unsigned port, phys_bytes source,
  387. 04841                 unsigned bytcount)                                      );
  388. 04842 _PROTOTYPE( void reset, (void)                                          );
  389. 04843 _PROTOTYPE( void vid_vid_copy, (unsigned src, unsigned dst, unsigned count));
  390. 04844 _PROTOTYPE( void mem_vid_copy, (u16_t *src, unsigned dst, unsigned count));
  391. 04845 _PROTOTYPE( void level0, (void (*func)(void))                           );
  392. 04846 _PROTOTYPE( void monitor, (void)                                        );
  393. 04847
  394. 04848 /* misc.c */
  395. 04849 _PROTOTYPE( void mem_init, (void)                                       );
  396. 04850
  397. 04851 /* mpx*.s */
  398. 04852 _PROTOTYPE( void idle_task, (void)                                      );
  399. 04853 _PROTOTYPE( void restart, (void)                                        );
  400. 04854
  401. 04855 /* The following are never called from C (pure asm procs). */
  402. 04856
  403. 04857 /* Exception handlers (real or protected mode), in numerical order. */
  404. 04858 void _PROTOTYPE( int00, (void) ), _PROTOTYPE( divide_error, (void) );
  405. 04859 void _PROTOTYPE( int01, (void) ), _PROTOTYPE( single_step_exception, (void) );
  406. 04860 void _PROTOTYPE( int02, (void) ), _PROTOTYPE( nmi, (void) );
  407. 04861 void _PROTOTYPE( int03, (void) ), _PROTOTYPE( breakpoint_exception, (void) );
  408. 04862 void _PROTOTYPE( int04, (void) ), _PROTOTYPE( overflow, (void) );
  409. 04863 void _PROTOTYPE( int05, (void) ), _PROTOTYPE( bounds_check, (void) );
  410. 04864 void _PROTOTYPE( int06, (void) ), _PROTOTYPE( inval_opcode, (void) );
  411. 04865 void _PROTOTYPE( int07, (void) ), _PROTOTYPE( copr_not_available, (void) );
  412. 04866 void                              _PROTOTYPE( double_fault, (void) );
  413. 04867 void                              _PROTOTYPE( copr_seg_overrun, (void) );
  414. 04868 void                              _PROTOTYPE( inval_tss, (void) );
  415. 04869 void                              _PROTOTYPE( segment_not_present, (void) );
  416. 04870 void                              _PROTOTYPE( stack_exception, (void) );
  417. 04871 void                              _PROTOTYPE( general_protection, (void) );
  418. 04872 void                              _PROTOTYPE( page_fault, (void) );
  419. 04873 void                              _PROTOTYPE( copr_error, (void) );
  420. 04874
  421. 04875 /* Hardware interrupt handlers. */
  422. 04876 _PROTOTYPE( void hwint00, (void) );
  423. 04877 _PROTOTYPE( void hwint01, (void) );
  424. 04878 _PROTOTYPE( void hwint02, (void) );
  425. 04879 _PROTOTYPE( void hwint03, (void) );
  426. 04880 _PROTOTYPE( void hwint04, (void) );
  427. 04881 _PROTOTYPE( void hwint05, (void) );
  428. 04882 _PROTOTYPE( void hwint06, (void) );
  429. 04883 _PROTOTYPE( void hwint07, (void) );
  430. 04884 _PROTOTYPE( void hwint08, (void) );
  431. 04885 _PROTOTYPE( void hwint09, (void) );
  432. 04886 _PROTOTYPE( void hwint10, (void) );
  433. 04887 _PROTOTYPE( void hwint11, (void) );
  434. 04888 _PROTOTYPE( void hwint12, (void) );
  435. 04889 _PROTOTYPE( void hwint13, (void) );
  436. 04890 _PROTOTYPE( void hwint14, (void) );
  437. 04891 _PROTOTYPE( void hwint15, (void) );
  438. 04892
  439. 04893 /* Software interrupt handlers, in numerical order. */
  440. 04894 _PROTOTYPE( void trp, (void) );
  441. 04895 _PROTOTYPE( void s_call, (void) ), _PROTOTYPE( p_s_call, (void) );
  442. 04896 _PROTOTYPE( void level0_call, (void) );
  443. 04897
  444. 04898 /* printer.c */
  445. 04899 _PROTOTYPE( void pr_restart, (void)                                     );
  446. 04900
  447. 04901 /* protect.c */
  448. 04902 _PROTOTYPE( void prot_init, (void)                                      );
  449. 04903 _PROTOTYPE( void init_codeseg, (struct segdesc_s *segdp, phys_bytes base,
  450. 04904                 phys_bytes size, int privilege)                         );
  451. 04905 _PROTOTYPE( void init_dataseg, (struct segdesc_s *segdp, phys_bytes base,
  452. 04906                 phys_bytes size, int privilege)                         );
  453. 04907 _PROTOTYPE( phys_bytes seg2phys, (U16_t seg)                            );
  454. 04908 _PROTOTYPE( void enable_iop, (struct proc *pp)                          );
  455. 04909
  456. 04910 /* pty.c */
  457. 04911 _PROTOTYPE( void do_pty, (struct tty *tp, message *m_ptr)               );
  458. 04912 _PROTOTYPE( void pty_init, (struct tty *tp)                             );
  459. 04913
  460. 04914 /* system.c */
  461. 04915 _PROTOTYPE( void alloc_segments, (struct proc *rp)                      );
  462. 04916
  463. 04917 #endif /* (CHIP == INTEL) */
  464. 04918
  465. 04919 #endif /* PROTO_H */
  466. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  467. src/kernel/glo.h    
  468. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  469. 05000 /* Global variables used in the kernel. */
  470. 05001
  471. 05002 /* EXTERN is defined as extern except in table.c. */
  472. 05003 #ifdef _TABLE
  473. 05004 #undef EXTERN
  474. 05005 #define EXTERN
  475. 05006 #endif
  476. 05007
  477. 05008 /* Kernel memory. */
  478. 05009 EXTERN phys_bytes code_base;    /* base of kernel code */
  479. 05010 EXTERN phys_bytes data_base;    /* base of kernel data */
  480. 05011
  481. 05012 /* Low level interrupt communications. */
  482. 05013 EXTERN struct proc *held_head;  /* head of queue of held-up interrupts */
  483. 05014 EXTERN struct proc *held_tail;  /* tail of queue of held-up interrupts */
  484. 05015 EXTERN unsigned char k_reenter; /* kernel reentry count (entry count less 1)*/
  485. 05016
  486. 05017 /* Process table.  Here to stop too many things having to include proc.h. */
  487. 05018 EXTERN struct proc *proc_ptr;   /* pointer to currently running process */
  488. 05019
  489. 05020 /* Signals. */
  490. 05021 EXTERN int sig_procs;           /* number of procs with p_pending != 0 */
  491. 05022
  492. 05023 /* Memory sizes. */
  493. 05024 EXTERN struct memory mem[NR_MEMS];      /* base and size of chunks of memory */
  494. 05025 EXTERN phys_clicks tot_mem_size;        /* total system memory size */
  495. 05026
  496. 05027 /* Miscellaneous. */
  497. 05028 extern u16_t sizes[];           /* table filled in by boot monitor */
  498. 05029 extern struct tasktab tasktab[];/* initialized in table.c, so extern here */
  499. 05030 extern char *t_stack[];         /* initialized in table.c, so extern here */
  500. 05031 EXTERN unsigned lost_ticks;     /* clock ticks counted outside the clock task */
  501. 05032 EXTERN clock_t tty_timeout;     /* time to wake up the TTY task */
  502. 05033 EXTERN int current;             /* currently visible console */
  503. 05034
  504. 05035 #if (CHIP == INTEL)
  505. 05036
  506. 05037 /* Machine type. */
  507. 05038 EXTERN int pc_at;               /* PC-AT compatible hardware interface */
  508. 05039 EXTERN int ps_mca;              /* PS/2 with Micro Channel */
  509. 05040 EXTERN unsigned int processor;  /* 86, 186, 286, 386, ... */
  510. 05041 #if _WORD_SIZE == 2
  511. 05042 EXTERN int protected_mode;      /* nonzero if running in Intel protected mode*/
  512. 05043 #else
  513. 05044 #define protected_mode  1       /* 386 mode implies protected mode */
  514. 05045 #endif
  515. 05046
  516. 05047 /* Video card types. */
  517. 05048 EXTERN int ega;                 /* nonzero if console is EGA or VGA */
  518. 05049 EXTERN int vga;                 /* nonzero if console is VGA */
  519. 05050
  520. 05051 /* Memory sizes. */
  521. 05052 EXTERN unsigned ext_memsize;    /* initialized by assembler startup code */
  522. 05053 EXTERN unsigned low_memsize;
  523. 05054
  524. 05055 /* Miscellaneous. */
  525. 05056 EXTERN irq_handler_t irq_table[NR_IRQ_VECTORS];
  526. 05057 EXTERN int irq_use;             /* bit map of all in-use irq's */
  527. 05058 EXTERN reg_t mon_ss, mon_sp;    /* monitor stack */
  528. 05059 EXTERN int mon_return;          /* true if return to the monitor possible */
  529. 05060 EXTERN phys_bytes reboot_code;  /* program for the boot monitor */
  530. 05061
  531. 05062 /* Variables that are initialized elsewhere are just extern here. */
  532. 05063 extern struct segdesc_s gdt[];  /* global descriptor table for protected mode*/
  533. 05064
  534. 05065 EXTERN _PROTOTYPE( void (*level0_func), (void) );
  535. 05066 #endif /* (CHIP == INTEL) */
  536. 05067
  537. 05068 #if (CHIP == M68000)
  538. 05069 /* Variables that are initialized elsewhere are just extern here. */
  539. 05070 extern int keypad;              /* Flag for keypad mode */
  540. 05071 extern int app_mode;            /* Flag for arrow key application mode */
  541. 05072 extern int STdebKey;            /* nonzero if ctl-alt-Fx detected */
  542. 05073 extern struct tty *cur_cons;    /* virtual cons currently displayed */
  543. 05074 extern unsigned char font8[];   /* 8 pixel wide font table (initialized) */
  544. 05075 extern unsigned char font12[];  /* 12 pixel wide font table (initialized) */
  545. 05076 extern unsigned char font16[];  /* 16 pixel wide font table (initialized) */
  546. 05077 extern unsigned short resolution; /* screen res; ST_RES_LOW..TT_RES_HIGH */
  547. 05078 #endif
  548. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  549. src/kernel/proc.h    
  550. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  551. 05100 #ifndef PROC_H
  552. 05101 #define PROC_H
  553. 05102
  554. 05103 /* Here is the declaration of the process table.  It contains the process'
  555. 05104  * registers, memory map, accounting, and message send/receive information.
  556. 05105  * Many assembly code routines reference fields in it.  The offsets to these
  557. 05106  * fields are defined in the assembler include file sconst.h.  When changing
  558. 05107  * 'proc', be sure to change sconst.h to match.
  559. 05108  */
  560. 05109
  561. 05110 struct proc {
  562. 05111   struct stackframe_s p_reg;    /* process' registers saved in stack frame */
  563. 05112
  564. 05113 #if (CHIP == INTEL)
  565. 05114   reg_t p_ldt_sel;              /* selector in gdt giving ldt base and limit*/
  566. 05115   struct segdesc_s p_ldt[2];    /* local descriptors for code and data */
  567. 05116                                 /* 2 is LDT_SIZE - avoid include protect.h */
  568. 05117 #endif /* (CHIP == INTEL) */
  569. 05118
  570. 05119   reg_t *p_stguard;             /* stack guard word */
  571. 05120
  572. 05121   int p_nr;                     /* number of this process (for fast access) */
  573. 05122
  574. 05123   int p_int_blocked;            /* nonzero if int msg blocked by busy task */
  575. 05124   int p_int_held;               /* nonzero if int msg held by busy syscall */
  576. 05125   struct proc *p_nextheld;      /* next in chain of held-up int processes */
  577. 05126
  578. 05127   int p_flags;                  /* P_SLOT_FREE, SENDING, RECEIVING, etc. */
  579. 05128   struct mem_map p_map[NR_SEGS];/* memory map */
  580. 05129   pid_t p_pid;                  /* process id passed in from MM */
  581. 05130
  582. 05131   clock_t user_time;            /* user time in ticks */
  583. 05132   clock_t sys_time;             /* sys time in ticks */
  584. 05133   clock_t child_utime;          /* cumulative user time of children */
  585. 05134   clock_t child_stime;          /* cumulative sys time of children */
  586. 05135   clock_t p_alarm;              /* time of next alarm in ticks, or 0 */
  587. 05136
  588. 05137   struct proc *p_callerq;       /* head of list of procs wishing to send */
  589. 05138   struct proc *p_sendlink;      /* link to next proc wishing to send */
  590. 05139   message *p_messbuf;           /* pointer to message buffer */
  591. 05140   int p_getfrom;                /* from whom does process want to receive? */
  592. 05141   int p_sendto;
  593. 05142
  594. 05143   struct proc *p_nextready;     /* pointer to next ready process */
  595. 05144   sigset_t p_pending;           /* bit map for pending signals */
  596. 05145   unsigned p_pendcount;         /* count of pending and unfinished signals */
  597. 05146
  598. 05147   char p_name[16];              /* name of the process */
  599. 05148 };
  600. 05149
  601. 05150 /* Guard word for task stacks. */
  602. 05151 #define STACK_GUARD     ((reg_t) (sizeof(reg_t) == 2 ? 0xBEEF : 0xDEADBEEF))
  603. 05152
  604. 05153 /* Bits for p_flags in proc[].  A process is runnable iff p_flags == 0. */
  605. 05154 #define P_SLOT_FREE      001    /* set when slot is not in use */
  606. 05155 #define NO_MAP           002    /* keeps unmapped forked child from running */
  607. 05156 #define SENDING          004    /* set when process blocked trying to send */
  608. 05157 #define RECEIVING        010    /* set when process blocked trying to recv */
  609. 05158 #define PENDING          020    /* set when inform() of signal pending */
  610. 05159 #define SIG_PENDING      040    /* keeps to-be-signalled proc from running */
  611. 05160 #define P_STOP          0100    /* set when process is being traced */
  612. 05161
  613. 05162 /* Magic process table addresses. */
  614. 05163 #define BEG_PROC_ADDR (&proc[0])
  615. 05164 #define END_PROC_ADDR (&proc[NR_TASKS + NR_PROCS])
  616. 05165 #define END_TASK_ADDR (&proc[NR_TASKS])
  617. 05166 #define BEG_SERV_ADDR (&proc[NR_TASKS])
  618. 05167 #define BEG_USER_ADDR (&proc[NR_TASKS + LOW_USER])
  619. 05168
  620. 05169 #define NIL_PROC          ((struct proc *) 0)
  621. 05170 #define isidlehardware(n) ((n) == IDLE || (n) == HARDWARE)
  622. 05171 #define isokprocn(n)      ((unsigned) ((n) + NR_TASKS) < NR_PROCS + NR_TASKS)
  623. 05172 #define isoksrc_dest(n)   (isokprocn(n) || (n) == ANY)
  624. 05173 #define isoksusern(n)     ((unsigned) (n) < NR_PROCS)
  625. 05174 #define isokusern(n)      ((unsigned) ((n) - LOW_USER) < NR_PROCS - LOW_USER)
  626. 05175 #define isrxhardware(n)   ((n) == ANY || (n) == HARDWARE)
  627. 05176 #define issysentn(n)      ((n) == FS_PROC_NR || (n) == MM_PROC_NR)
  628. 05177 #define istaskp(p)        ((p) < END_TASK_ADDR && (p) != proc_addr(IDLE))
  629. 05178 #define isuserp(p)        ((p) >= BEG_USER_ADDR)
  630. 05179 #define proc_addr(n)      (pproc_addr + NR_TASKS)[(n)]
  631. 05180 #define cproc_addr(n)     (&(proc + NR_TASKS)[(n)])
  632. 05181 #define proc_number(p)    ((p)->p_nr)
  633. 05182 #define proc_vir2phys(p, vir) 
  634. 05183                           (((phys_bytes)(p)->p_map[D].mem_phys << CLICK_SHIFT) 
  635. 05184                                                         + (vir_bytes) (vir))
  636. 05185
  637. 05186 EXTERN struct proc proc[NR_TASKS + NR_PROCS];   /* process table */
  638. 05187 EXTERN struct proc *pproc_addr[NR_TASKS + NR_PROCS];
  639. 05188 /* ptrs to process table slots; fast because now a process entry can be found
  640. 05189    by indexing the pproc_addr array, while accessing an element i requires
  641. 05190    a multiplication with sizeof(struct proc) to determine the address */
  642. 05191 EXTERN struct proc *bill_ptr;   /* ptr to process to bill for clock ticks */
  643. 05192 EXTERN struct proc *rdy_head[NQ];       /* pointers to ready list headers */
  644. 05193 EXTERN struct proc *rdy_tail[NQ];       /* pointers to ready list tails */
  645. 05194
  646. 05195 #endif /* PROC_H */
  647. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  648. src/kernel/protect.h    
  649. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  650. 05200 /* Constants for protected mode. */
  651. 05201
  652. 05202 /* Table sizes. */
  653. 05203 #define GDT_SIZE (FIRST_LDT_INDEX + NR_TASKS + NR_PROCS) /* spec. and LDT's */
  654. 05204 #define IDT_SIZE (IRQ8_VECTOR + 8)      /* only up to the highest vector */
  655. 05205 #define LDT_SIZE         2      /* contains CS and DS only */
  656. 05206
  657. 05207 /* Fixed global descriptors.  1 to 7 are prescribed by the BIOS. */
  658. 05208 #define GDT_INDEX        1      /* GDT descriptor */
  659. 05209 #define IDT_INDEX        2      /* IDT descriptor */
  660. 05210 #define DS_INDEX         3      /* kernel DS */
  661. 05211 #define ES_INDEX         4      /* kernel ES (386: flag 4 Gb at startup) */
  662. 05212 #define SS_INDEX         5      /* kernel SS (386: monitor SS at startup) */
  663. 05213 #define CS_INDEX         6      /* kernel CS */
  664. 05214 #define MON_CS_INDEX     7      /* temp for BIOS (386: monitor CS at startup) */
  665. 05215 #define TSS_INDEX        8      /* kernel TSS */
  666. 05216 #define DS_286_INDEX     9      /* scratch 16-bit source segment */
  667. 05217 #define ES_286_INDEX    10      /* scratch 16-bit destination segment */
  668. 05218 #define VIDEO_INDEX     11      /* video memory segment */
  669. 05219 #define DP_ETH0_INDEX   12      /* Western Digital Etherplus buffer */
  670. 05220 #define DP_ETH1_INDEX   13      /* Western Digital Etherplus buffer */
  671. 05221 #define FIRST_LDT_INDEX 14      /* rest of descriptors are LDT's */
  672. 05222
  673. 05223 #define GDT_SELECTOR      0x08  /* (GDT_INDEX * DESC_SIZE) bad for asld */
  674. 05224 #define IDT_SELECTOR      0x10  /* (IDT_INDEX * DESC_SIZE) */
  675. 05225 #define DS_SELECTOR       0x18  /* (DS_INDEX * DESC_SIZE) */
  676. 05226 #define ES_SELECTOR       0x20  /* (ES_INDEX * DESC_SIZE) */
  677. 05227 #define FLAT_DS_SELECTOR  0x21  /* less privileged ES */
  678. 05228 #define SS_SELECTOR       0x28  /* (SS_INDEX * DESC_SIZE) */
  679. 05229 #define CS_SELECTOR       0x30  /* (CS_INDEX * DESC_SIZE) */
  680. 05230 #define MON_CS_SELECTOR   0x38  /* (MON_CS_INDEX * DESC_SIZE) */
  681. 05231 #define TSS_SELECTOR      0x40  /* (TSS_INDEX * DESC_SIZE) */
  682. 05232 #define DS_286_SELECTOR   0x49  /* (DS_286_INDEX * DESC_SIZE + 1) */
  683. 05233 #define ES_286_SELECTOR   0x51  /* (ES_286_INDEX * DESC_SIZE + 1) */
  684. 05234 #define VIDEO_SELECTOR    0x59  /* (VIDEO_INDEX * DESC_SIZE + 1) */
  685. 05235 #define DP_ETH0_SELECTOR  0x61  /* (DP_ETH0_INDEX * DESC_SIZE) */
  686. 05236 #define DP_ETH1_SELECTOR  0x69  /* (DP_ETH1_INDEX * DESC_SIZE) */
  687. 05237
  688. 05238 /* Fixed local descriptors. */
  689. 05239 #define CS_LDT_INDEX     0      /* process CS */
  690. 05240 #define DS_LDT_INDEX     1      /* process DS=ES=FS=GS=SS */
  691. 05241
  692. 05242 /* Privileges. */
  693. 05243 #define INTR_PRIVILEGE   0      /* kernel and interrupt handlers */
  694. 05244 #define TASK_PRIVILEGE   1
  695. 05245 #define USER_PRIVILEGE   3
  696. 05246
  697. 05247 /* 286 hardware constants. */
  698. 05248
  699. 05249 /* Exception vector numbers. */
  700. 05250 #define BOUNDS_VECTOR       5   /* bounds check failed */
  701. 05251 #define INVAL_OP_VECTOR     6   /* invalid opcode */
  702. 05252 #define COPROC_NOT_VECTOR   7   /* coprocessor not available */
  703. 05253 #define DOUBLE_FAULT_VECTOR 8
  704. 05254 #define COPROC_SEG_VECTOR   9   /* coprocessor segment overrun */
  705. 05255 #define INVAL_TSS_VECTOR   10   /* invalid TSS */
  706. 05256 #define SEG_NOT_VECTOR     11   /* segment not present */
  707. 05257 #define STACK_FAULT_VECTOR 12   /* stack exception */
  708. 05258 #define PROTECTION_VECTOR  13   /* general protection */
  709. 05259
  710. 05260 /* Selector bits. */
  711. 05261 #define TI            0x04      /* table indicator */
  712. 05262 #define RPL           0x03      /* requester privilege level */
  713. 05263
  714. 05264 /* Descriptor structure offsets. */
  715. 05265 #define DESC_BASE        2      /* to base_low */
  716. 05266 #define DESC_BASE_MIDDLE 4      /* to base_middle */
  717. 05267 #define DESC_ACCESS      5      /* to access byte */
  718. 05268 #define DESC_SIZE        8      /* sizeof (struct segdesc_s) */
  719. 05269
  720. 05270 /* Segment sizes. */
  721. 05271 #define MAX_286_SEG_SIZE 0x10000L
  722. 05272
  723. 05273 /* Base and limit sizes and shifts. */
  724. 05274 #define BASE_MIDDLE_SHIFT   16  /* shift for base --> base_middle */
  725. 05275
  726. 05276 /* Access-byte and type-byte bits. */
  727. 05277 #define PRESENT       0x80      /* set for descriptor present */
  728. 05278 #define DPL           0x60      /* descriptor privilege level mask */
  729. 05279 #define DPL_SHIFT        5
  730. 05280 #define SEGMENT       0x10      /* set for segment-type descriptors */
  731. 05281
  732. 05282 /* Access-byte bits. */
  733. 05283 #define EXECUTABLE    0x08      /* set for executable segment */
  734. 05284 #define CONFORMING    0x04      /* set for conforming segment if executable */
  735. 05285 #define EXPAND_DOWN   0x04      /* set for expand-down segment if !executable*/
  736. 05286 #define READABLE      0x02      /* set for readable segment if executable */
  737. 05287 #define WRITEABLE     0x02      /* set for writeable segment if !executable */
  738. 05288 #define TSS_BUSY      0x02      /* set if TSS descriptor is busy */
  739. 05289 #define ACCESSED      0x01      /* set if segment accessed */
  740. 05290
  741. 05291 /* Special descriptor types. */
  742. 05292 #define AVL_286_TSS      1      /* available 286 TSS */
  743. 05293 #define LDT              2      /* local descriptor table */
  744. 05294 #define BUSY_286_TSS     3      /* set transparently to the software */
  745. 05295 #define CALL_286_GATE    4      /* not used */
  746. 05296 #define TASK_GATE        5      /* only used by debugger */
  747. 05297 #define INT_286_GATE     6      /* interrupt gate, used for all vectors */
  748. 05298 #define TRAP_286_GATE    7      /* not used */
  749. 05299
  750. 05300 /* Extra 386 hardware constants. */
  751. 05301
  752. 05302 /* Exception vector numbers. */
  753. 05303 #define PAGE_FAULT_VECTOR   14
  754. 05304 #define COPROC_ERR_VECTOR   16  /* coprocessor error */
  755. 05305
  756. 05306 /* Descriptor structure offsets. */
  757. 05307 #define DESC_GRANULARITY     6  /* to granularity byte */
  758. 05308 #define DESC_BASE_HIGH       7  /* to base_high */
  759. 05309
  760. 05310 /* Base and limit sizes and shifts. */
  761. 05311 #define BASE_HIGH_SHIFT     24  /* shift for base --> base_high */
  762. 05312 #define BYTE_GRAN_MAX   0xFFFFFL   /* maximum size for byte granular segment */
  763. 05313 #define GRANULARITY_SHIFT   16  /* shift for limit --> granularity */
  764. 05314 #define OFFSET_HIGH_SHIFT   16  /* shift for (gate) offset --> offset_high */
  765. 05315 #define PAGE_GRAN_SHIFT     12  /* extra shift for page granular limits */
  766. 05316
  767. 05317 /* Type-byte bits. */
  768. 05318 #define DESC_386_BIT      0x08  /* 386 types are obtained by ORing with this */
  769. 05319                                 /* LDT's and TASK_GATE's don't need it */
  770. 05320
  771. 05321 /* Granularity byte. */
  772. 05322 #define GRANULAR          0x80  /* set for 4K granularilty */
  773. 05323 #define DEFAULT           0x40  /* set for 32-bit defaults (executable seg) */
  774. 05324 #define BIG               0x40  /* set for "BIG" (expand-down seg) */
  775. 05325 #define AVL               0x10  /* 0 for available */
  776. 05326 #define LIMIT_HIGH        0x0F  /* mask for high bits of limit */
  777. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  778. src/kernel/sconst.h    
  779. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  780. 05400 ! Miscellaneous constants used in assembler code.
  781. 05401 W               =       _WORD_SIZE      ! Machine word size.
  782. 05402
  783. 05403 ! Offsets in struct proc. They MUST match proc.h.
  784. 05404 P_STACKBASE     =       0
  785. 05405 #if _WORD_SIZE == 2
  786. 05406 ESREG           =       P_STACKBASE
  787. 05407 #else
  788. 05408 GSREG           =       P_STACKBASE
  789. 05409 FSREG           =       GSREG + 2       ! 386 introduces FS and GS segments
  790. 05410 ESREG           =       FSREG + 2
  791. 05411 #endif
  792. 05412 DSREG           =       ESREG + 2
  793. 05413 DIREG           =       DSREG + 2
  794. 05414 SIREG           =       DIREG + W
  795. 05415 BPREG           =       SIREG + W
  796. 05416 STREG           =       BPREG + W       ! hole for another SP
  797. 05417 BXREG           =       STREG + W
  798. 05418 DXREG           =       BXREG + W
  799. 05419 CXREG           =       DXREG + W
  800. 05420 AXREG           =       CXREG + W
  801. 05421 RETADR          =       AXREG + W       ! return address for save() call
  802. 05422 PCREG           =       RETADR + W
  803. 05423 CSREG           =       PCREG + W
  804. 05424 PSWREG          =       CSREG + W
  805. 05425 SPREG           =       PSWREG + W
  806. 05426 SSREG           =       SPREG + W
  807. 05427 P_STACKTOP      =       SSREG + W
  808. 05428 P_LDT_SEL       =       P_STACKTOP
  809. 05429 P_LDT           =       P_LDT_SEL + W
  810. 05430
  811. 05431 #if _WORD_SIZE == 2
  812. 05432 Msize           =       12              ! size of a message in 16-bit words
  813. 05433 #else
  814. 05434 Msize           =       9               ! size of a message in 32-bit words
  815. 05435 #endif
  816. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  817. src/kernel/assert.h    
  818. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  819. 05500 /*
  820. 05501 assert.h
  821. 05502 */
  822. 05503 #ifndef ASSERT_H
  823. 05504 #define ASSERT_H
  824. 05505
  825. 05506 #if DEBUG
  826. 05507
  827. 05508 #define INIT_ASSERT     static char *assert_file= __FILE__;
  828. 05509
  829. 05510 void bad_assertion(char *file, int line, char *what);
  830. 05511 void bad_compare(char *file, int line, int lhs, char *what, int rhs);
  831. 05512
  832. 05513 #define assert(x)       (!(x) ? bad_assertion(assert_file, __LINE__, #x) 
  833. 05514                                                                 : (void) 0)
  834. 05515 #define compare(a,t,b)  (!((a) t (b)) ? bad_compare(assert_file, __LINE__, 
  835. 05516                                 (a), #a " " #t " " #b, (b)) : (void) 0)
  836. 05517 #else /* !DEBUG */
  837. 05518
  838. 05519 #define INIT_ASSERT     /* nothing */
  839. 05520
  840. 05521 #define assert(x)       (void)0
  841. 05522 #define compare(a,t,b)  (void)0
  842. 05523
  843. 05524 #endif /* !DEBUG */
  844. 05525
  845. 05526 #endif /* ASSERT_H */
  846. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  847. src/kernel/table.c    
  848. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  849. 05600 /* The object file of "table.c" contains all the data.  In the *.h files, 
  850. 05601  * declared variables appear with EXTERN in front of them, as in
  851. 05602  *
  852. 05603  *    EXTERN int x;
  853. 05604  *
  854. 05605  * Normally EXTERN is defined as extern, so when they are included in another
  855. 05606  * file, no storage is allocated.  If the EXTERN were not present, but just
  856. 05607  * say,
  857. 05608  *
  858. 05609  *    int x;
  859. 05610  *
  860. 05611  * then including this file in several source files would cause 'x' to be
  861. 05612  * declared several times.  While some linkers accept this, others do not,
  862. 05613  * so they are declared extern when included normally.  However, it must
  863. 05614  * be declared for real somewhere.  That is done here, by redefining
  864. 05615  * EXTERN as the null string, so the inclusion of all the *.h files in
  865. 05616  * table.c actually generates storage for them.  All the initialized
  866. 05617  * variables are also declared here, since
  867. 05618  *
  868. 05619  * extern int x = 4;
  869. 05620  *
  870. 05621  * is not allowed.  If such variables are shared, they must also be declared
  871. 05622  * in one of the *.h files without the initialization.
  872. 05623  */
  873. 05624
  874. 05625 #define _TABLE
  875. 05626
  876. 05627 #include "kernel.h"
  877. 05628 #include <termios.h>
  878. 05629 #include <minix/com.h>
  879. 05630 #include "proc.h"
  880. 05631 #include "tty.h"
  881. 05632
  882. 05633 /* The startup routine of each task is given below, from -NR_TASKS upwards.
  883. 05634  * The order of the names here MUST agree with the numerical values assigned to
  884. 05635  * the tasks in <minix/com.h>.
  885. 05636  */
  886. 05637 #define SMALL_STACK     (128 * sizeof(char *))
  887. 05638
  888. 05639 #define TTY_STACK       (3 * SMALL_STACK)
  889. 05640 #define SYN_ALRM_STACK  SMALL_STACK
  890. 05641
  891. 05642 #define DP8390_STACK    (SMALL_STACK * ENABLE_NETWORKING)
  892. 05643
  893. 05644 #if (CHIP == INTEL)
  894. 05645 #define IDLE_STACK      ((3+3+4) * sizeof(char *))  /* 3 intr, 3 temps, 4 db */
  895. 05646 #else
  896. 05647 #define IDLE_STACK      SMALL_STACK
  897. 05648 #endif
  898. 05649
  899. 05650 #define PRINTER_STACK   SMALL_STACK
  900. 05651
  901. 05652 #if (CHIP == INTEL)
  902. 05653 #define WINCH_STACK     (2 * SMALL_STACK * ENABLE_WINI)
  903. 05654 #else
  904. 05655 #define WINCH_STACK     (3 * SMALL_STACK * ENABLE_WINI)
  905. 05656 #endif
  906. 05657
  907. 05658 #if (MACHINE == ATARI)
  908. 05659 #define SCSI_STACK      (3 * SMALL_STACK)
  909. 05660 #endif
  910. 05661
  911. 05662 #if (MACHINE == IBM_PC)
  912. 05663 #define SCSI_STACK      (2 * SMALL_STACK * ENABLE_SCSI)
  913. 05664 #endif
  914. 05665
  915. 05666 #define CDROM_STACK     (4 * SMALL_STACK * ENABLE_CDROM)
  916. 05667 #define AUDIO_STACK     (4 * SMALL_STACK * ENABLE_AUDIO)
  917. 05668 #define MIXER_STACK     (4 * SMALL_STACK * ENABLE_AUDIO)
  918. 05669
  919. 05670 #define FLOP_STACK      (3 * SMALL_STACK)
  920. 05671 #define MEM_STACK       SMALL_STACK
  921. 05672 #define CLOCK_STACK     SMALL_STACK
  922. 05673 #define SYS_STACK       SMALL_STACK
  923. 05674 #define HARDWARE_STACK  0               /* dummy task, uses kernel stack */
  924. 05675
  925. 05676
  926. 05677 #define TOT_STACK_SPACE         (TTY_STACK + DP8390_STACK + SCSI_STACK + 
  927. 05678         SYN_ALRM_STACK + IDLE_STACK + HARDWARE_STACK + PRINTER_STACK + 
  928. 05679         WINCH_STACK + FLOP_STACK + MEM_STACK + CLOCK_STACK + SYS_STACK + 
  929. 05680         CDROM_STACK + AUDIO_STACK + MIXER_STACK)
  930. 05681
  931. 05682
  932. 05683 /* SCSI, CDROM and AUDIO may in the future have different choices like
  933. 05684  * WINCHESTER, but for now the choice is fixed.
  934. 05685  */
  935. 05686 #define scsi_task       aha_scsi_task
  936. 05687 #define cdrom_task      mcd_task
  937. 05688 #define audio_task      dsp_task
  938. 05689
  939. 05690
  940. 05691 /*
  941. 05692  * Some notes about the following table:
  942. 05693  *  1) The tty_task should always be first so that other tasks can use printf
  943. 05694  *     if their initialisation has problems.
  944. 05695  *  2) If you add a new kernel task, add it before the printer task.
  945. 05696  *  3) The task name is used for the process name (p_name).
  946. 05697  */
  947. 05698
  948. 05699 PUBLIC struct tasktab tasktab[] = {
  949. 05700         { tty_task,             TTY_STACK,      "TTY"           },
  950. 05701 #if ENABLE_NETWORKING
  951. 05702         { dp8390_task,          DP8390_STACK,   "DP8390"        },
  952. 05703 #endif
  953. 05704 #if ENABLE_CDROM
  954. 05705         { cdrom_task,           CDROM_STACK,    "CDROM"         },
  955. 05706 #endif
  956. 05707 #if ENABLE_AUDIO
  957. 05708         { audio_task,           AUDIO_STACK,    "AUDIO"         },
  958. 05709         { mixer_task,           MIXER_STACK,    "MIXER"         },
  959. 05710 #endif
  960. 05711 #if ENABLE_SCSI
  961. 05712         { scsi_task,            SCSI_STACK,     "SCSI"          },
  962. 05713 #endif
  963. 05714 #if ENABLE_WINI
  964. 05715         { winchester_task,      WINCH_STACK,    "WINCH"         },
  965. 05716 #endif
  966. 05717         { syn_alrm_task,        SYN_ALRM_STACK, "SYN_AL"        },
  967. 05718         { idle_task,            IDLE_STACK,     "IDLE"          },
  968. 05719         { printer_task,         PRINTER_STACK,  "PRINTER"       },
  969. 05720         { floppy_task,          FLOP_STACK,     "FLOPPY"        },
  970. 05721         { mem_task,             MEM_STACK,      "MEMORY"        },
  971. 05722         { clock_task,           CLOCK_STACK,    "CLOCK"         },
  972. 05723         { sys_task,             SYS_STACK,      "SYS"           },
  973. 05724         { 0,                    HARDWARE_STACK, "HARDWAR"       },
  974. 05725         { 0,                    0,              "MM"            },
  975. 05726         { 0,                    0,              "FS"            },
  976. 05727 #if ENABLE_NETWORKING
  977. 05728         { 0,                    0,              "INET"          },
  978. 05729 #endif
  979. 05730         { 0,                    0,              "INIT"          },
  980. 05731 };
  981. 05732
  982. 05733 /* Stack space for all the task stacks.  (Declared as (char *) to align it.) */
  983. 05734 PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
  984. 05735
  985. 05736 /*
  986. 05737  * The number of kernel tasks must be the same as NR_TASKS.
  987. 05738  * If NR_TASKS is not correct then you will get the compile error:
  988. 05739  *   "array size is negative"
  989. 05740  */
  990. 05741
  991. 05742 #define NKT (sizeof tasktab / sizeof (struct tasktab) - (INIT_PROC_NR + 1))
  992. 05743
  993. 05744 extern int dummy_tasktab_check[NR_TASKS == NKT ? 1 : -1];
  994. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  995. src/kernel/mpx.s    
  996. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  997. 05800 #
  998. 05801 ! Chooses between the 8086 and 386 versions of the Minix startup code.
  999. 05802
  1000. 05803 #include <minix/config.h>
  1001. 05804 #if _WORD_SIZE == 2
  1002. 05805 #include "mpx88.s"
  1003. 05806 #else
  1004. 05807 #include "mpx386.s"
  1005. 05808 #endif
  1006. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1007. src/kernel/mpx386.s    
  1008. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1009. 05900 #
  1010. 05901 ! This file contains the assembler startup code for Minix and the 32-bit
  1011. 05902 ! interrupt handlers.  It cooperates with start.c to set up a good
  1012. 05903 ! environment for main().
  1013. 05904
  1014. 05905 ! This file is part of the lowest layer of the MINIX kernel.  The other part
  1015. 05906 ! is "proc.c".  The lowest layer does process switching and message handling.
  1016. 05907
  1017. 05908 ! Every transition to the kernel goes through this file.  Transitions are
  1018. 05909 ! caused by sending/receiving messages and by most interrupts.  (RS232
  1019. 05910 ! interrupts may be handled in the file "rs2.s" and then they rarely enter
  1020. 05911 ! the kernel.)
  1021. 05912
  1022. 05913 ! Transitions to the kernel may be nested.  The initial entry may be with a
  1023. 05914 ! system call, exception or hardware interrupt; reentries may only be made
  1024. 05915 ! by hardware interrupts.  The count of reentries is kept in "k_reenter".
  1025. 05916 ! It is important for deciding whether to switch to the kernel stack and
  1026. 05917 ! for protecting the message passing code in "proc.c".
  1027. 05918
  1028. 05919 ! For the message passing trap, most of the machine state is saved in the
  1029. 05920 ! proc table.  (Some of the registers need not be saved.)  Then the stack is
  1030. 05921 ! switched to "k_stack", and interrupts are reenabled.  Finally, the system
  1031. 05922 ! call handler (in C) is called.  When it returns, interrupts are disabled
  1032. 05923 ! again and the code falls into the restart routine, to finish off held-up
  1033. 05924 ! interrupts and run the process or task whose pointer is in "proc_ptr".
  1034. 05925
  1035. 05926 ! Hardware interrupt handlers do the same, except  (1) The entire state must
  1036. 05927 ! be saved.  (2) There are too many handlers to do this inline, so the save
  1037. 05928 ! routine is called.  A few cycles are saved by pushing the address of the
  1038. 05929 ! appropiate restart routine for a return later.  (3) A stack switch is
  1039. 05930 ! avoided when the stack is already switched.  (4) The (master) 8259 interrupt
  1040. 05931 ! controller is reenabled centrally in save().  (5) Each interrupt handler
  1041. 05932 ! masks its interrupt line using the 8259 before enabling (other unmasked)
  1042. 05933 ! interrupts, and unmasks it after servicing the interrupt.  This limits the
  1043. 05934 ! nest level to the number of lines and protects the handler from itself.
  1044. 05935
  1045. 05936 ! For communication with the boot monitor at startup time some constant
  1046. 05937 ! data are compiled into the beginning of the text segment. This facilitates 
  1047. 05938 ! reading the data at the start of the boot process, since only the first
  1048. 05939 ! sector of the file needs to be read.
  1049. 05940
  1050. 05941 ! Some data storage is also allocated at the end of this file. This data 
  1051. 05942 ! will be at the start of the data segment of the kernel and will be read
  1052. 05943 ! and modified by the boot monitor before the kernel starts.
  1053. 05944
  1054. 05945 ! sections
  1055. 05946
  1056. 05947 .sect .text
  1057. 05948 begtext:
  1058. 05949 .sect .rom
  1059. 05950 begrom:
  1060. 05951 .sect .data
  1061. 05952 begdata:
  1062. 05953 .sect .bss
  1063. 05954 begbss:
  1064. 05955
  1065. 05956 #include <minix/config.h>
  1066. 05957 #include <minix/const.h>
  1067. 05958 #include <minix/com.h>
  1068. 05959 #include "const.h"
  1069. 05960 #include "protect.h"
  1070. 05961 #include "sconst.h"
  1071. 05962
  1072. 05963 /* Selected 386 tss offsets. */
  1073. 05964 #define TSS3_S_SP0      4
  1074. 05965
  1075. 05966 ! Exported functions
  1076. 05967 ! Note: in assembly language the .define statement applied to a function name 
  1077. 05968 ! is loosely equivalent to a prototype in C code -- it makes it possible to
  1078. 05969 ! link to an entity declared in the assembly code but does not create
  1079. 05970 ! the entity.
  1080. 05971
  1081. 05972 .define _idle_task
  1082. 05973 .define _restart
  1083. 05974 .define save
  1084. 05975
  1085. 05976 .define _divide_error
  1086. 05977 .define _single_step_exception
  1087. 05978 .define _nmi
  1088. 05979 .define _breakpoint_exception
  1089. 05980 .define _overflow
  1090. 05981 .define _bounds_check
  1091. 05982 .define _inval_opcode
  1092. 05983 .define _copr_not_available
  1093. 05984 .define _double_fault
  1094. 05985 .define _copr_seg_overrun
  1095. 05986 .define _inval_tss
  1096. 05987 .define _segment_not_present
  1097. 05988 .define _stack_exception
  1098. 05989 .define _general_protection
  1099. 05990 .define _page_fault
  1100. 05991 .define _copr_error
  1101. 05992
  1102. 05993 .define _hwint00        ! handlers for hardware interrupts
  1103. 05994 .define _hwint01
  1104. 05995 .define _hwint02
  1105. 05996 .define _hwint03
  1106. 05997 .define _hwint04
  1107. 05998 .define _hwint05
  1108. 05999 .define _hwint06
  1109. 06000 .define _hwint07
  1110. 06001 .define _hwint08
  1111. 06002 .define _hwint09
  1112. 06003 .define _hwint10
  1113. 06004 .define _hwint11
  1114. 06005 .define _hwint12
  1115. 06006 .define _hwint13
  1116. 06007 .define _hwint14
  1117. 06008 .define _hwint15
  1118. 06009
  1119. 06010 .define _s_call
  1120. 06011 .define _p_s_call
  1121. 06012 .define _level0_call
  1122. 06013
  1123. 06014 ! Imported functions.
  1124. 06015
  1125. 06016 .extern _cstart
  1126. 06017 .extern _main
  1127. 06018 .extern _exception
  1128. 06019 .extern _interrupt
  1129. 06020 .extern _sys_call
  1130. 06021 .extern _unhold
  1131. 06022
  1132. 06023 ! Exported variables.
  1133. 06024 ! Note: when used with a variable the .define does not reserve storage,
  1134. 06025 ! it makes the name externally visible so it may be linked to. 
  1135. 06026
  1136. 06027 .define begbss
  1137. 06028 .define begdata
  1138. 06029 .define _sizes
  1139. 06030
  1140. 06031 ! Imported variables.
  1141. 06032
  1142. 06033 .extern _gdt
  1143. 06034 .extern _code_base
  1144. 06035 .extern _data_base
  1145. 06036 .extern _held_head
  1146. 06037 .extern _k_reenter
  1147. 06038 .extern _pc_at
  1148. 06039 .extern _proc_ptr
  1149. 06040 .extern _ps_mca
  1150. 06041 .extern _tss
  1151. 06042 .extern _level0_func
  1152. 06043 .extern _mon_sp
  1153. 06044 .extern _mon_return
  1154. 06045 .extern _reboot_code
  1155. 06046
  1156. 06047 .sect .text
  1157. 06048 !*===========================================================================*
  1158. 06049 !*                              MINIX                                        *
  1159. 06050 !*===========================================================================*
  1160. 06051 MINIX:                          ! this is the entry point for the MINIX kernel
  1161. 06052         jmp     over_flags      ! skip over the next few bytes
  1162. 06053         .data2  CLICK_SHIFT     ! for the monitor: memory granularity
  1163. 06054 flags:
  1164. 06055         .data2  0x002D          ! boot monitor flags:
  1165. 06056                                 !       call in 386 mode, make stack,
  1166. 06057                                 !       load high, will return
  1167. 06058         nop                     ! extra byte to sync up disassembler
  1168. 06059 over_flags:
  1169. 06060
  1170. 06061 ! Set up a C stack frame on the monitor stack.  (The monitor sets cs and ds
  1171. 06062 ! right.  The ss descriptor still references the monitor data segment.)
  1172. 06063         movzx   esp, sp         ! monitor stack is a 16 bit stack
  1173. 06064         push    ebp
  1174. 06065         mov     ebp, esp
  1175. 06066         push    esi
  1176. 06067         push    edi
  1177. 06068         cmp     4(ebp), 0       ! nonzero if return possible
  1178. 06069         jz      noret
  1179. 06070         inc     (_mon_return)
  1180. 06071 noret:  mov     (_mon_sp), esp  ! save stack pointer for later return
  1181. 06072
  1182. 06073 ! Copy the monitor global descriptor table to the address space of kernel and
  1183. 06074 ! switch over to it.  Prot_init() can then update it with immediate effect.
  1184. 06075
  1185. 06076         sgdt    (_gdt+GDT_SELECTOR)             ! get the monitor gdtr
  1186. 06077         mov     esi, (_gdt+GDT_SELECTOR+2)      ! absolute address of GDT
  1187. 06078         mov     ebx, _gdt                       ! address of kernel GDT
  1188. 06079         mov     ecx, 8*8                        ! copying eight descriptors
  1189. 06080 copygdt:
  1190. 06081  eseg   movb    al, (esi)
  1191. 06082         movb    (ebx), al
  1192. 06083         inc     esi
  1193. 06084         inc     ebx
  1194. 06085         loop    copygdt
  1195. 06086         mov     eax, (_gdt+DS_SELECTOR+2)       ! base of kernel data
  1196. 06087         and     eax, 0x00FFFFFF                 ! only 24 bits
  1197. 06088         add     eax, _gdt                       ! eax = vir2phys(gdt)
  1198. 06089         mov     (_gdt+GDT_SELECTOR+2), eax      ! set base of GDT
  1199. 06090         lgdt    (_gdt+GDT_SELECTOR)             ! switch over to kernel GDT
  1200. 06091
  1201. 06092 ! Locate boot parameters, set up kernel segment registers and stack.
  1202. 06093         mov     ebx, 8(ebp)     ! boot parameters offset
  1203. 06094         mov     edx, 12(ebp)    ! boot parameters length
  1204. 06095         mov     ax, ds          ! kernel data
  1205. 06096         mov     es, ax
  1206. 06097         mov     fs, ax
  1207. 06098         mov     gs, ax
  1208. 06099         mov     ss, ax
  1209. 06100         mov     esp, k_stktop   ! set sp to point to the top of kernel stack
  1210. 06101
  1211. 06102 ! Call C startup code to set up a proper environment to run main().
  1212. 06103         push    edx
  1213. 06104         push    ebx
  1214. 06105         push    SS_SELECTOR
  1215. 06106         push    MON_CS_SELECTOR
  1216. 06107         push    DS_SELECTOR
  1217. 06108         push    CS_SELECTOR
  1218. 06109         call    _cstart         ! cstart(cs, ds, mcs, mds, parmoff, parmlen)
  1219. 06110         add     esp, 6*4
  1220. 06111
  1221. 06112 ! Reload gdtr, idtr and the segment registers to global descriptor table set
  1222. 06113 ! up by prot_init().
  1223. 06114
  1224. 06115         lgdt    (_gdt+GDT_SELECTOR)
  1225. 06116         lidt    (_gdt+IDT_SELECTOR)
  1226. 06117
  1227. 06118         jmpf    CS_SELECTOR:csinit
  1228. 06119 csinit:
  1229. 06120     o16 mov     ax, DS_SELECTOR
  1230. 06121         mov     ds, ax
  1231. 06122         mov     es, ax
  1232. 06123         mov     fs, ax
  1233. 06124         mov     gs, ax
  1234. 06125         mov     ss, ax
  1235. 06126     o16 mov     ax, TSS_SELECTOR        ! no other TSS is used
  1236. 06127         ltr     ax
  1237. 06128         push    0                       ! set flags to known good state
  1238. 06129         popf                            ! esp, clear nested task and int enable
  1239. 06130
  1240. 06131         jmp     _main                   ! main()
  1241. 06132
  1242. 06133
  1243. 06134 !*===========================================================================*
  1244. 06135 !*                              interrupt handlers                           *
  1245. 06136 !*              interrupt handlers for 386 32-bit protected mode             *
  1246. 06137 !*===========================================================================*
  1247. 06138
  1248. 06139 !*===========================================================================*
  1249. 06140 !*                              hwint00 - 07                                 *
  1250. 06141 !*===========================================================================*
  1251. 06142 ! Note this is a macro, it looks like a subroutine.
  1252. 06143 #define hwint_master(irq)       
  1253. 06144         call    save                    /* save interrupted process state */;
  1254. 06145         inb     INT_CTLMASK                                                 ;
  1255. 06146         orb     al, [1<<irq]                                                ;
  1256. 06147         outb    INT_CTLMASK             /* disable the irq                */;
  1257. 06148         movb    al, ENABLE                                                  ;
  1258. 06149         outb    INT_CTL                 /* reenable master 8259           */;
  1259. 06150         sti                             /* enable interrupts              */;
  1260. 06151         push    irq                     /* irq                            */;
  1261. 06152         call    (_irq_table + 4*irq)    /* eax = (*irq_table[irq])(irq)   */;
  1262. 06153         pop     ecx                                                         ;
  1263. 06154         cli                             /* disable interrupts             */;
  1264. 06155         test    eax, eax                /* need to reenable irq?          */;
  1265. 06156         jz      0f                                                          ;
  1266. 06157         inb     INT_CTLMASK                                                 ;
  1267. 06158         andb    al, ~[1<<irq]                                               ;
  1268. 06159         outb    INT_CTLMASK             /* enable the irq                 */;
  1269. 06160 0:      ret                             /* restart (another) process      */
  1270. 06161
  1271. 06162 ! Each of these entry points is an expansion of the hwint_master macro
  1272. 06163         .align  16
  1273. 06164 _hwint00:               ! Interrupt routine for irq 0 (the clock).
  1274. 06165         hwint_master(0)
  1275. 06166
  1276. 06167         .align  16
  1277. 06168 _hwint01:               ! Interrupt routine for irq 1 (keyboard)
  1278. 06169         hwint_master(1)
  1279. 06170
  1280. 06171         .align  16
  1281. 06172 _hwint02:               ! Interrupt routine for irq 2 (cascade!)
  1282. 06173         hwint_master(2)
  1283. 06174
  1284. 06175         .align  16
  1285. 06176 _hwint03:               ! Interrupt routine for irq 3 (second serial)
  1286. 06177         hwint_master(3)
  1287. 06178
  1288. 06179         .align  16
  1289. 06180 _hwint04:               ! Interrupt routine for irq 4 (first serial)
  1290. 06181         hwint_master(4)
  1291. 06182
  1292. 06183         .align  16
  1293. 06184 _hwint05:               ! Interrupt routine for irq 5 (XT winchester)
  1294. 06185         hwint_master(5)
  1295. 06186
  1296. 06187         .align  16
  1297. 06188 _hwint06:               ! Interrupt routine for irq 6 (floppy)
  1298. 06189         hwint_master(6)
  1299. 06190
  1300. 06191         .align  16
  1301. 06192 _hwint07:               ! Interrupt routine for irq 7 (printer)
  1302. 06193         hwint_master(7)
  1303. 06194
  1304. 06195 !*===========================================================================*
  1305. 06196 !*                              hwint08 - 15                                 *
  1306. 06197 !*===========================================================================*
  1307. 06198 ! Note this is a macro, it looks like a subroutine.
  1308. 06199 #define hwint_slave(irq)        
  1309. 06200         call    save                    /* save interrupted process state */;
  1310. 06201         inb     INT2_CTLMASK                                                ;
  1311. 06202         orb     al, [1<<[irq-8]]                                            ;
  1312. 06203         outb    INT2_CTLMASK            /* disable the irq                */;
  1313. 06204         movb    al, ENABLE                                                  ;
  1314. 06205         outb    INT_CTL                 /* reenable master 8259           */;
  1315. 06206         jmp     .+2                     /* delay                          */;
  1316. 06207         outb    INT2_CTL                /* reenable slave 8259            */;
  1317. 06208         sti                             /* enable interrupts              */;
  1318. 06209         push    irq                     /* irq                            */;
  1319. 06210         call    (_irq_table + 4*irq)    /* eax = (*irq_table[irq])(irq)   */;
  1320. 06211         pop     ecx                                                         ;
  1321. 06212         cli                             /* disable interrupts             */;
  1322. 06213         test    eax, eax                /* need to reenable irq?          */;
  1323. 06214         jz      0f                                                          ;
  1324. 06215         inb     INT2_CTLMASK                                                ;
  1325. 06216         andb    al, ~[1<<[irq-8]]                                           ;
  1326. 06217         outb    INT2_CTLMASK            /* enable the irq                 */;
  1327. 06218 0:      ret                             /* restart (another) process      */
  1328. 06219
  1329. 06220 ! Each of these entry points is an expansion of the hwint_slave macro
  1330. 06221         .align  16
  1331. 06222 _hwint08:               ! Interrupt routine for irq 8 (realtime clock)
  1332. 06223         hwint_slave(8)
  1333. 06224
  1334. 06225         .align  16
  1335. 06226 _hwint09:               ! Interrupt routine for irq 9 (irq 2 redirected)
  1336. 06227         hwint_slave(9)
  1337. 06228
  1338. 06229         .align  16
  1339. 06230 _hwint10:               ! Interrupt routine for irq 10
  1340. 06231         hwint_slave(10)
  1341. 06232
  1342. 06233         .align  16
  1343. 06234 _hwint11:               ! Interrupt routine for irq 11
  1344. 06235         hwint_slave(11)
  1345. 06236
  1346. 06237         .align  16
  1347. 06238 _hwint12:               ! Interrupt routine for irq 12
  1348. 06239         hwint_slave(12)
  1349. 06240
  1350. 06241         .align  16
  1351. 06242 _hwint13:               ! Interrupt routine for irq 13 (FPU exception)
  1352. 06243         hwint_slave(13)
  1353. 06244
  1354. 06245         .align  16
  1355. 06246 _hwint14:               ! Interrupt routine for irq 14 (AT winchester)
  1356. 06247         hwint_slave(14)
  1357. 06248
  1358. 06249         .align  16
  1359. 06250 _hwint15:               ! Interrupt routine for irq 15
  1360. 06251         hwint_slave(15)
  1361. 06252
  1362. 06253 !*===========================================================================*
  1363. 06254 !*                              save                                         *
  1364. 06255 !*===========================================================================*
  1365. 06256 ! Save for protected mode.
  1366. 06257 ! This is much simpler than for 8086 mode, because the stack already points
  1367. 06258 ! into the process table, or has already been switched to the kernel stack.
  1368. 06259
  1369. 06260         .align  16
  1370. 06261 save:
  1371. 06262         cld                     ! set direction flag to a known value
  1372. 06263         pushad                  ! save "general" registers
  1373. 06264     o16 push    ds              ! save ds
  1374. 06265     o16 push    es              ! save es
  1375. 06266     o16 push    fs              ! save fs
  1376. 06267     o16 push    gs              ! save gs
  1377. 06268         mov     dx, ss          ! ss is kernel data segment
  1378. 06269         mov     ds, dx          ! load rest of kernel segments
  1379. 06270         mov     es, dx          ! kernel does not use fs, gs
  1380. 06271         mov     eax, esp        ! prepare to return
  1381. 06272         incb    (_k_reenter)    ! from -1 if not reentering
  1382. 06273         jnz     set_restart1    ! stack is already kernel stack
  1383. 06274         mov     esp, k_stktop
  1384. 06275         push    _restart        ! build return address for int handler
  1385. 06276         xor     ebp, ebp        ! for stacktrace
  1386. 06277         jmp     RETADR-P_STACKBASE(eax)
  1387. 06278
  1388. 06279         .align  4
  1389. 06280 set_restart1:
  1390. 06281         push    restart1
  1391. 06282         jmp     RETADR-P_STACKBASE(eax)
  1392. 06283
  1393. 06284 !*===========================================================================*
  1394. 06285 !*                              _s_call                                      *
  1395. 06286 !*===========================================================================*
  1396. 06287         .align  16
  1397. 06288 _s_call:
  1398. 06289 _p_s_call:
  1399. 06290         cld                     ! set direction flag to a known value
  1400. 06291         sub     esp, 6*4        ! skip RETADR, eax, ecx, edx, ebx, est
  1401. 06292         push    ebp             ! stack already points into proc table
  1402. 06293         push    esi
  1403. 06294         push    edi
  1404. 06295     o16 push    ds
  1405. 06296     o16 push    es
  1406. 06297     o16 push    fs
  1407. 06298     o16 push    gs
  1408. 06299         mov     dx, ss
  1409. 06300         mov     ds, dx
  1410. 06301         mov     es, dx
  1411. 06302         incb    (_k_reenter)
  1412. 06303         mov     esi, esp        ! assumes P_STACKBASE == 0
  1413. 06304         mov     esp, k_stktop
  1414. 06305         xor     ebp, ebp        ! for stacktrace
  1415. 06306                                 ! end of inline save
  1416. 06307         sti                     ! allow SWITCHER to be interrupted
  1417. 06308                                 ! now set up parameters for sys_call()
  1418. 06309         push    ebx             ! pointer to user message
  1419. 06310         push    eax             ! src/dest
  1420. 06311         push    ecx             ! SEND/RECEIVE/BOTH
  1421. 06312         call    _sys_call       ! sys_call(function, src_dest, m_ptr)
  1422. 06313                                 ! caller is now explicitly in proc_ptr
  1423. 06314         mov     AXREG(esi), eax ! sys_call MUST PRESERVE si
  1424. 06315         cli                     ! disable interrupts 
  1425. 06316
  1426. 06317 ! Fall into code to restart proc/task running.
  1427. 06318
  1428. 06319 !*===========================================================================*
  1429. 06320 !*                              restart                                      *
  1430. 06321 !*===========================================================================*
  1431. 06322 _restart:
  1432. 06323
  1433. 06324 ! Flush any held-up interrupts.
  1434. 06325 ! This reenables interrupts, so the current interrupt handler may reenter.
  1435. 06326 ! This does not matter, because the current handler is about to exit and no
  1436. 06327 ! other handlers can reenter since flushing is only done when k_reenter == 0.
  1437. 06328
  1438. 06329         cmp     (_held_head), 0 ! do fast test to usually avoid function call
  1439. 06330         jz      over_call_unhold
  1440. 06331         call    _unhold         ! this is rare so overhead acceptable
  1441. 06332 over_call_unhold:
  1442. 06333         mov     esp, (_proc_ptr)        ! will assume P_STACKBASE == 0
  1443. 06334         lldt    P_LDT_SEL(esp)          ! enable segment descriptors for task
  1444. 06335         lea     eax, P_STACKTOP(esp)    ! arrange for next interrupt
  1445. 06336         mov     (_tss+TSS3_S_SP0), eax  ! to save state in process table
  1446. 06337 restart1:
  1447. 06338         decb    (_k_reenter)
  1448. 06339     o16 pop     gs
  1449. 06340     o16 pop     fs
  1450. 06341     o16 pop     es
  1451. 06342     o16 pop     ds
  1452. 06343         popad
  1453. 06344         add     esp, 4          ! skip return adr
  1454. 06345         iretd                   ! continue process
  1455. 06346
  1456. 06347 !*===========================================================================*
  1457. 06348 !*                              exception handlers                           *
  1458. 06349 !*===========================================================================*
  1459. 06350 _divide_error:
  1460. 06351         push    DIVIDE_VECTOR
  1461. 06352         jmp     exception
  1462. 06353
  1463. 06354 _single_step_exception:
  1464. 06355         push    DEBUG_VECTOR
  1465. 06356         jmp     exception
  1466. 06357
  1467. 06358 _nmi:
  1468. 06359         push    NMI_VECTOR
  1469. 06360         jmp     exception
  1470. 06361
  1471. 06362 _breakpoint_exception:
  1472. 06363         push    BREAKPOINT_VECTOR
  1473. 06364         jmp     exception
  1474. 06365
  1475. 06366 _overflow:
  1476. 06367         push    OVERFLOW_VECTOR
  1477. 06368         jmp     exception
  1478. 06369
  1479. 06370 _bounds_check:
  1480. 06371         push    BOUNDS_VECTOR
  1481. 06372         jmp     exception
  1482. 06373
  1483. 06374 _inval_opcode:
  1484. 06375         push    INVAL_OP_VECTOR
  1485. 06376         jmp     exception
  1486. 06377
  1487. 06378 _copr_not_available:
  1488. 06379         push    COPROC_NOT_VECTOR
  1489. 06380         jmp     exception
  1490. 06381
  1491. 06382 _double_fault:
  1492. 06383         push    DOUBLE_FAULT_VECTOR
  1493. 06384         jmp     errexception
  1494. 06385
  1495. 06386 _copr_seg_overrun:
  1496. 06387         push    COPROC_SEG_VECTOR
  1497. 06388         jmp     exception
  1498. 06389
  1499. 06390 _inval_tss:
  1500. 06391         push    INVAL_TSS_VECTOR
  1501. 06392         jmp     errexception
  1502. 06393
  1503. 06394 _segment_not_present:
  1504. 06395         push    SEG_NOT_VECTOR
  1505. 06396         jmp     errexception
  1506. 06397
  1507. 06398 _stack_exception:
  1508. 06399         push    STACK_FAULT_VECTOR
  1509. 06400         jmp     errexception
  1510. 06401
  1511. 06402 _general_protection:
  1512. 06403         push    PROTECTION_VECTOR
  1513. 06404         jmp     errexception
  1514. 06405
  1515. 06406 _page_fault:
  1516. 06407         push    PAGE_FAULT_VECTOR
  1517. 06408         jmp     errexception
  1518. 06409
  1519. 06410 _copr_error:
  1520. 06411         push    COPROC_ERR_VECTOR
  1521. 06412         jmp     exception
  1522. 06413
  1523. 06414 !*===========================================================================*
  1524. 06415 !*                              exception                                    *
  1525. 06416 !*===========================================================================*
  1526. 06417 ! This is called for all exceptions which do not push an error code.
  1527. 06418
  1528. 06419         .align  16
  1529. 06420 exception:
  1530. 06421  sseg   mov     (trap_errno), 0         ! clear trap_errno
  1531. 06422  sseg   pop     (ex_number)
  1532. 06423         jmp     exception1
  1533. 06424
  1534. 06425 !*===========================================================================*
  1535. 06426 !*                              errexception                                 *
  1536. 06427 !*===========================================================================*
  1537. 06428 ! This is called for all exceptions which push an error code.
  1538. 06429
  1539. 06430         .align  16
  1540. 06431 errexception:
  1541. 06432  sseg   pop     (ex_number)
  1542. 06433  sseg   pop     (trap_errno)
  1543. 06434 exception1:                             ! Common for all exceptions.
  1544. 06435         push    eax                     ! eax is scratch register
  1545. 06436         mov     eax, 0+4(esp)           ! old eip
  1546. 06437  sseg   mov     (old_eip), eax
  1547. 06438         movzx   eax, 4+4(esp)           ! old cs
  1548. 06439  sseg   mov     (old_cs), eax
  1549. 06440         mov     eax, 8+4(esp)           ! old eflags
  1550. 06441  sseg   mov     (old_eflags), eax
  1551. 06442         pop     eax
  1552. 06443         call    save
  1553. 06444         push    (old_eflags)
  1554. 06445         push    (old_cs)
  1555. 06446         push    (old_eip)
  1556. 06447         push    (trap_errno)
  1557. 06448         push    (ex_number)
  1558. 06449         call    _exception              ! (ex_number, trap_errno, old_eip,
  1559. 06450                                         !       old_cs, old_eflags)
  1560. 06451         add     esp, 5*4
  1561. 06452         cli
  1562. 06453         ret
  1563. 06454
  1564. 06455 !*===========================================================================*
  1565. 06456 !*                              level0_call                                  *
  1566. 06457 !*===========================================================================*
  1567. 06458 _level0_call:
  1568. 06459         call    save
  1569. 06460         jmp     (_level0_func)
  1570. 06461
  1571. 06462 !*===========================================================================*
  1572. 06463 !*                              idle_task                                    *
  1573. 06464 !*===========================================================================*
  1574. 06465 _idle_task:                     ! executed when there is no work
  1575. 06466         jmp     _idle_task      ! a "hlt" before this fails in protected mode
  1576. 06467
  1577. 06468 !*===========================================================================*
  1578. 06469 !*                              data                                         *
  1579. 06470 !*===========================================================================*
  1580. 06471 ! These declarations assure that storage will be allocated at the very 
  1581. 06472 ! beginning of the kernel data section, so the boot monitor can be easily 
  1582. 06473 ! told how to patch these locations. Note that the magic number is put
  1583. 06474 ! here by the compiler, but will be read by, and then overwritten by,
  1584. 06475 ! the boot monitor. When the kernel starts the sizes array will be
  1585. 06476 ! found here, as if it had been initialized by the compiler.
  1586. 06477
  1587. 06478 .sect .rom      ! Before the string table please
  1588. 06479 _sizes:                         ! sizes of kernel, mm, fs filled in by boot
  1589. 06480         .data2  0x526F          ! this must be the first data entry (magic #)
  1590. 06481         .space  16*2*2-2        ! monitor uses previous word and this space
  1591. 06482                                 ! extra space allows for additional servers
  1592. 06483 .sect .bss
  1593. 06484 k_stack:
  1594. 06485         .space  K_STACK_BYTES   ! kernel stack
  1595. 06486 k_stktop:                       ! top of kernel stack
  1596. 06487         .comm   ex_number, 4
  1597. 06488         .comm   trap_errno, 4
  1598. 06489         .comm   old_eip, 4
  1599. 06490         .comm   old_cs, 4
  1600. 06491         .comm   old_eflags, 4
  1601. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1602. src/kernel/start.c    
  1603. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1604. 06500 /* This file contains the C startup code for Minix on Intel processors.
  1605. 06501  * It cooperates with mpx.s to set up a good environment for main().
  1606. 06502  *
  1607. 06503  * This code runs in real mode for a 16 bit kernel and may have to switch
  1608. 06504  * to protected mode for a 286.
  1609. 06505  *
  1610. 06506  * For a 32 bit kernel this already runs in protected mode, but the selectors
  1611. 06507  * are still those given by the BIOS with interrupts disabled, so the
  1612. 06508  * descriptors need to be reloaded and interrupt descriptors made.
  1613. 06509  */
  1614. 06510
  1615. 06511 #include "kernel.h"
  1616. 06512 #include <stdlib.h>
  1617. 06513 #include <minix/boot.h>
  1618. 06514 #include "protect.h"
  1619. 06515
  1620. 06516 PRIVATE char k_environ[256];    /* environment strings passed by loader */
  1621. 06517
  1622. 06518 FORWARD _PROTOTYPE( int k_atoi, (char *s) );
  1623. 06519
  1624. 06520
  1625. 06521 /*==========================================================================*
  1626. 06522  *                              cstart                                      *
  1627. 06523  *==========================================================================*/
  1628. 06524 PUBLIC void cstart(cs, ds, mcs, mds, parmoff, parmsize)
  1629. 06525 U16_t cs, ds;                   /* Kernel code and data segment */
  1630. 06526 U16_t mcs, mds;                 /* Monitor code and data segment */
  1631. 06527 U16_t parmoff, parmsize;        /* boot parameters offset and length */
  1632. 06528 {
  1633. 06529 /* Perform system initializations prior to calling main(). */
  1634. 06530
  1635. 06531   register char *envp;
  1636. 06532   phys_bytes mcode_base, mdata_base;
  1637. 06533   unsigned mon_start;
  1638. 06534
  1639. 06535   /* Record where the kernel and the monitor are. */
  1640. 06536   code_base = seg2phys(cs);
  1641. 06537   data_base = seg2phys(ds);
  1642. 06538   mcode_base = seg2phys(mcs);
  1643. 06539   mdata_base = seg2phys(mds);
  1644. 06540
  1645. 06541   /* Initialize protected mode descriptors. */
  1646. 06542   prot_init();
  1647. 06543
  1648. 06544   /* Copy the boot parameters to kernel memory. */
  1649. 06545   if (parmsize > sizeof k_environ - 2) parmsize = sizeof k_environ - 2;
  1650. 06546   phys_copy(mdata_base + parmoff, vir2phys(k_environ), (phys_bytes) parmsize);
  1651. 06547
  1652. 06548   /* Convert important boot environment variables. */
  1653. 06549   boot_parameters.bp_rootdev = k_atoi(k_getenv("rootdev"));
  1654. 06550   boot_parameters.bp_ramimagedev = k_atoi(k_getenv("ramimagedev"));
  1655. 06551   boot_parameters.bp_ramsize = k_atoi(k_getenv("ramsize"));
  1656. 06552   boot_parameters.bp_processor = k_atoi(k_getenv("processor"));
  1657. 06553
  1658. 06554   /* Type of VDU: */
  1659. 06555   envp = k_getenv("video");
  1660. 06556   if (strcmp(envp, "ega") == 0) ega = TRUE;
  1661. 06557   if (strcmp(envp, "vga") == 0) vga = ega = TRUE;
  1662. 06558
  1663. 06559   /* Memory sizes: */
  1664. 06560   low_memsize = k_atoi(k_getenv("memsize"));
  1665. 06561   ext_memsize = k_atoi(k_getenv("emssize"));
  1666. 06562
  1667. 06563   /* Processor? */
  1668. 06564   processor = boot_parameters.bp_processor;     /* 86, 186, 286, 386, ... */
  1669. 06565
  1670. 06566   /* XT, AT or MCA bus? */
  1671. 06567   envp = k_getenv("bus");
  1672. 06568   if (envp == NIL_PTR || strcmp(envp, "at") == 0) {
  1673. 06569         pc_at = TRUE;
  1674. 06570   } else
  1675. 06571   if (strcmp(envp, "mca") == 0) {
  1676. 06572         pc_at = ps_mca = TRUE;
  1677. 06573   }
  1678. 06574
  1679. 06575   /* Decide if mode is protected. */
  1680. 06576 #if _WORD_SIZE == 2
  1681. 06577   protected_mode = processor >= 286;
  1682. 06578 #endif
  1683. 06579
  1684. 06580   /* Is there a monitor to return to?  If so then keep it safe. */
  1685. 06581   if (!protected_mode) mon_return = 0;
  1686. 06582   mon_start = mcode_base / 1024;
  1687. 06583   if (mon_return && low_memsize > mon_start) low_memsize = mon_start;
  1688. 06584
  1689. 06585   /* Return to assembler code to switch to protected mode (if 286), reload
  1690. 06586    * selectors and call main().
  1691. 06587    */
  1692. 06588 }
  1693. 06591 /*==========================================================================*
  1694. 06592  *                              k_atoi                                      *
  1695. 06593  *==========================================================================*/
  1696. 06594 PRIVATE int k_atoi(s)
  1697. 06595 register char *s;
  1698. 06596 {
  1699. 06597 /* Convert string to integer. */
  1700. 06598
  1701. 06599   return strtol(s, (char **) NULL, 10);
  1702. 06600 }
  1703. 06603 /*==========================================================================*
  1704. 06604  *                              k_getenv                                    *
  1705. 06605  *==========================================================================*/
  1706. 06606 PUBLIC char *k_getenv(name)
  1707. 06607 char *name;
  1708. 06608 {
  1709. 06609 /* Get environment value - kernel version of getenv to avoid setting up the
  1710. 06610  * usual environment array.
  1711. 06611  */
  1712. 06612
  1713. 06613   register char *namep;
  1714. 06614   register char *envp;
  1715. 06615
  1716. 06616   for (envp = k_environ; *envp != 0;) {
  1717. 06617         for (namep = name; *namep != 0 && *namep == *envp; namep++, envp++)
  1718. 06618                 ;
  1719. 06619         if (*namep == '' && *envp == '=') return(envp + 1);
  1720. 06620         while (*envp++ != 0)
  1721. 06621                 ;
  1722. 06622   }
  1723. 06623   return(NIL_PTR);
  1724. 06624 }
  1725. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1726. src/kernel/main.c    
  1727. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1728. 06700 /* This file contains the main program of MINIX.  The routine main()
  1729. 06701  * initializes the system and starts the ball rolling by setting up the proc
  1730. 06702  * table, interrupt vectors, and scheduling each task to run to initialize
  1731. 06703  * itself.
  1732. 06704  *
  1733. 06705  * The entries into this file are:
  1734. 06706  *   main:              MINIX main program
  1735. 06707  *   panic:             abort MINIX due to a fatal error
  1736. 06708  */
  1737. 06709
  1738. 06710 #include "kernel.h"
  1739. 06711 #include <signal.h>
  1740. 06712 #include <unistd.h>
  1741. 06713 #include <minix/callnr.h>
  1742. 06714 #include <minix/com.h>
  1743. 06715 #include "proc.h"
  1744. 06716
  1745. 06717
  1746. 06718 /*===========================================================================*
  1747. 06719  *                                   main                                    *
  1748. 06720  *===========================================================================*/
  1749. 06721 PUBLIC void main()
  1750. 06722 {
  1751. 06723 /* Start the ball rolling. */
  1752. 06724
  1753. 06725   register struct proc *rp;
  1754. 06726   register int t;
  1755. 06727   int sizeindex;
  1756. 06728   phys_clicks text_base;
  1757. 06729   vir_clicks text_clicks;
  1758. 06730   vir_clicks data_clicks;
  1759. 06731   phys_bytes phys_b;
  1760. 06732   reg_t ktsb;                   /* kernel task stack base */
  1761. 06733   struct memory *memp;
  1762. 06734   struct tasktab *ttp;
  1763. 06735
  1764. 06736   /* Initialize the interrupt controller. */
  1765. 06737   intr_init(1);
  1766. 06738
  1767. 06739   /* Interpret memory sizes. */
  1768. 06740   mem_init();
  1769. 06741
  1770. 06742   /* Clear the process table.
  1771. 06743    * Set up mappings for proc_addr() and proc_number() macros.
  1772. 06744    */
  1773. 06745   for (rp = BEG_PROC_ADDR, t = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++t) {
  1774. 06746         rp->p_flags = P_SLOT_FREE;
  1775. 06747         rp->p_nr = t;           /* proc number from ptr */
  1776. 06748         (pproc_addr + NR_TASKS)[t] = rp;        /* proc ptr from number */
  1777. 06749   }
  1778. 06750
  1779. 06751   /* Set up proc table entries for tasks and servers.  The stacks of the
  1780. 06752    * kernel tasks are initialized to an array in data space.  The stacks
  1781. 06753    * of the servers have been added to the data segment by the monitor, so
  1782. 06754    * the stack pointer is set to the end of the data segment.  All the
  1783. 06755    * processes are in low memory on the 8086.  On the 386 only the kernel
  1784. 06756    * is in low memory, the rest if loaded in extended memory.
  1785. 06757    */
  1786. 06758
  1787. 06759   /* Task stacks. */
  1788. 06760   ktsb = (reg_t) t_stack;
  1789. 06761
  1790. 06762   for (t = -NR_TASKS; t <= LOW_USER; ++t) {
  1791. 06763         rp = proc_addr(t);                      /* t's process slot */
  1792. 06764         ttp = &tasktab[t + NR_TASKS];           /* t's task attributes */
  1793. 06765         strcpy(rp->p_name, ttp->name);
  1794. 06766         if (t < 0) {
  1795. 06767                 if (ttp->stksize > 0) {
  1796. 06768                         rp->p_stguard = (reg_t *) ktsb;
  1797. 06769                         *rp->p_stguard = STACK_GUARD;
  1798. 06770                 }
  1799. 06771                 ktsb += ttp->stksize;
  1800. 06772                 rp->p_reg.sp = ktsb;
  1801. 06773                 text_base = code_base >> CLICK_SHIFT;
  1802. 06774                                         /* tasks are all in the kernel */
  1803. 06775                 sizeindex = 0;          /* and use the full kernel sizes */
  1804. 06776                 memp = &mem[0];         /* remove from this memory chunk */
  1805. 06777         } else {
  1806. 06778                 sizeindex = 2 * t + 2;  /* MM, FS, INIT have their own sizes */
  1807. 06779         }
  1808. 06780         rp->p_reg.pc = (reg_t) ttp->initial_pc;
  1809. 06781         rp->p_reg.psw = istaskp(rp) ? INIT_TASK_PSW : INIT_PSW;
  1810. 06782
  1811. 06783         text_clicks = sizes[sizeindex];
  1812. 06784         data_clicks = sizes[sizeindex + 1];
  1813. 06785         rp->p_map[T].mem_phys = text_base;
  1814. 06786         rp->p_map[T].mem_len  = text_clicks;
  1815. 06787         rp->p_map[D].mem_phys = text_base + text_clicks;
  1816. 06788         rp->p_map[D].mem_len  = data_clicks;
  1817. 06789         rp->p_map[S].mem_phys = text_base + text_clicks + data_clicks;
  1818. 06790         rp->p_map[S].mem_vir  = data_clicks;    /* empty - stack is in data */
  1819. 06791         text_base += text_clicks + data_clicks; /* ready for next, if server */
  1820. 06792         memp->size -= (text_base - memp->base);
  1821. 06793         memp->base = text_base;                 /* memory no longer free */
  1822. 06794
  1823. 06795         if (t >= 0) {
  1824. 06796                 /* Initialize the server stack pointer.  Take it down one word
  1825. 06797                  * to give crtso.s something to use as "argc".
  1826. 06798                  */
  1827. 06799                 rp->p_reg.sp = (rp->p_map[S].mem_vir +
  1828. 06800                                 rp->p_map[S].mem_len) << CLICK_SHIFT;
  1829. 06801                 rp->p_reg.sp -= sizeof(reg_t);
  1830. 06802         }
  1831. 06803
  1832. 06804 #if _WORD_SIZE == 4
  1833. 06805         /* Servers are loaded in extended memory if in 386 mode. */
  1834. 06806         if (t < 0) {
  1835. 06807                 memp = &mem[1];
  1836. 06808                 text_base = 0x100000 >> CLICK_SHIFT;
  1837. 06809         }
  1838. 06810 #endif
  1839. 06811         if (!isidlehardware(t)) lock_ready(rp); /* IDLE, HARDWARE neveready */
  1840. 06812         rp->p_flags = 0;
  1841. 06813
  1842. 06814         alloc_segments(rp);
  1843. 06815   }
  1844. 06816
  1845. 06817   proc[NR_TASKS+INIT_PROC_NR].p_pid = 1;/* INIT of course has pid 1 */
  1846. 06818   bill_ptr = proc_addr(IDLE);           /* it has to point somewhere */
  1847. 06819   lock_pick_proc();
  1848. 06820
  1849. 06821   /* Now go to the assembly code to start running the current process. */
  1850. 06822   restart();
  1851. 06823 }
  1852. 06826 /*===========================================================================*
  1853. 06827  *                                   panic                                   *
  1854. 06828  *===========================================================================*/
  1855. 06829 PUBLIC void panic(s,n)
  1856. 06830 _CONST char *s;
  1857. 06831 int n;
  1858. 06832 {
  1859. 06833 /* The system has run aground of a fatal error.  Terminate execution.
  1860. 06834  * If the panic originated in MM or FS, the string will be empty and the
  1861. 06835  * file system already syncked.  If the panic originates in the kernel, we are
  1862. 06836  * kind of stuck.
  1863. 06837  */
  1864. 06838
  1865. 06839   if (*s != 0) {
  1866. 06840         printf("nKernel panic: %s",s);
  1867. 06841         if (n != NO_NUM) printf(" %d", n);
  1868. 06842         printf("n");
  1869. 06843   }
  1870. 06844   wreboot(RBT_PANIC);
  1871. 06845 }
  1872. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1873. src/kernel/proc.c    
  1874. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1875. 06900 /* This file contains essentially all of the process and message handling.
  1876. 06901  * It has two main entry points from the outside:
  1877. 06902  *
  1878. 06903  *   sys_call:   called when a process or task does SEND, RECEIVE or SENDREC
  1879. 06904  *   interrupt: called by interrupt routines to send a message to task
  1880. 06905  *
  1881. 06906  * It also has several minor entry points:
  1882. 06907  *
  1883. 06908  *   lock_ready:      put a process on one of the ready queues so it can be run
  1884. 06909  *   lock_unready:    remove a process from the ready queues
  1885. 06910  *   lock_sched:      a process has run too long; schedule another one
  1886. 06911  *   lock_mini_send:  send a message (used by interrupt signals, etc.)
  1887. 06912  *   lock_pick_proc:  pick a process to run (used by system initialization)
  1888. 06913  *   unhold:          repeat all held-up interrupts
  1889. 06914  */
  1890. 06915
  1891. 06916 #include "kernel.h"
  1892. 06917 #include <minix/callnr.h>
  1893. 06918 #include <minix/com.h>
  1894. 06919 #include "proc.h"
  1895. 06920
  1896. 06921 PRIVATE unsigned char switching;        /* nonzero to inhibit interrupt() */
  1897. 06922
  1898. 06923 FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dest,
  1899. 06924                 message *m_ptr) );
  1900. 06925 FORWARD _PROTOTYPE( int mini_rec, (struct proc *caller_ptr, int src,
  1901. 06926                 message *m_ptr) );
  1902. 06927 FORWARD _PROTOTYPE( void ready, (struct proc *rp) );
  1903. 06928 FORWARD _PROTOTYPE( void sched, (void) );
  1904. 06929 FORWARD _PROTOTYPE( void unready, (struct proc *rp) );
  1905. 06930 FORWARD _PROTOTYPE( void pick_proc, (void) );
  1906. 06931
  1907. 06932 #define CopyMess(s,sp,sm,dp,dm) 
  1908. 06933         cp_mess(s, (sp)->p_map[D].mem_phys, (vir_bytes)sm, (dp)->p_map[D].mem_phys, (vir_bytes)dm)
  1909. 06934
  1910. 06935 /*===========================================================================*
  1911. 06936  *                              interrupt                                    * 
  1912. 06937  *===========================================================================*/
  1913. 06938 PUBLIC void interrupt(task)
  1914. 06939 int task;                       /* number of task to be started */
  1915. 06940 {
  1916. 06941 /* An interrupt has occurred.  Schedule the task that handles it. */
  1917. 06942
  1918. 06943   register struct proc *rp;     /* pointer to task's proc entry */
  1919. 06944
  1920. 06945   rp = proc_addr(task);
  1921. 06946
  1922. 06947   /* If this call would compete with other process-switching functions, put
  1923. 06948    * it on the 'held' queue to be flushed at the next non-competing restart().
  1924. 06949    * The competing conditions are:
  1925. 06950    * (1) k_reenter == (typeof k_reenter) -1:
  1926. 06951    *     Call from the task level, typically from an output interrupt
  1927. 06952    *     routine.  An interrupt handler might reenter interrupt().  Rare,
  1928. 06953    *     so not worth special treatment.
  1929. 06954    * (2) k_reenter > 0:
  1930. 06955    *     Call from a nested interrupt handler.  A previous interrupt handler
  1931. 06956    *     might be inside interrupt() or sys_call().
  1932. 06957    * (3) switching != 0:
  1933. 06958    *     Some process-switching function other than interrupt() is being
  1934. 06959    *     called from the task level, typically sched() from CLOCK.  An
  1935. 06960    *     interrupt handler might call interrupt and pass the k_reenter test.
  1936. 06961    */
  1937. 06962   if (k_reenter != 0 || switching) {
  1938. 06963         lock();
  1939. 06964         if (!rp->p_int_held) {
  1940. 06965                 rp->p_int_held = TRUE;
  1941. 06966                 if (held_head != NIL_PROC)
  1942. 06967                         held_tail->p_nextheld = rp;
  1943. 06968                 else
  1944. 06969                         held_head = rp;
  1945. 06970                 held_tail = rp;
  1946. 06971                 rp->p_nextheld = NIL_PROC;
  1947. 06972         }
  1948. 06973         unlock();
  1949. 06974         return;
  1950. 06975   }
  1951. 06976
  1952. 06977   /* If task is not waiting for an interrupt, record the blockage. */
  1953. 06978   if ( (rp->p_flags & (RECEIVING | SENDING)) != RECEIVING ||
  1954. 06979       !isrxhardware(rp->p_getfrom)) {
  1955. 06980         rp->p_int_blocked = TRUE;
  1956. 06981         return;
  1957. 06982   }
  1958. 06983
  1959. 06984   /* Destination is waiting for an interrupt.
  1960. 06985    * Send it a message with source HARDWARE and type HARD_INT.
  1961. 06986    * No more information can be reliably provided since interrupt messages
  1962. 06987    * are not queued.
  1963. 06988    */
  1964. 06989   rp->p_messbuf->m_source = HARDWARE;
  1965. 06990   rp->p_messbuf->m_type = HARD_INT;
  1966. 06991   rp->p_flags &= ~RECEIVING;
  1967. 06992   rp->p_int_blocked = FALSE;
  1968. 06993
  1969. 06994    /* Make rp ready and run it unless a task is already running.  This is
  1970. 06995     * ready(rp) in-line for speed.
  1971. 06996     */
  1972. 06997   if (rdy_head[TASK_Q] != NIL_PROC)
  1973. 06998         rdy_tail[TASK_Q]->p_nextready = rp;
  1974. 06999   else
  1975. 07000         proc_ptr = rdy_head[TASK_Q] = rp;
  1976. 07001   rdy_tail[TASK_Q] = rp;
  1977. 07002   rp->p_nextready = NIL_PROC;
  1978. 07003 }
  1979. 07005 /*===========================================================================*
  1980. 07006  *                              sys_call                                     * 
  1981. 07007  *===========================================================================*/
  1982. 07008 PUBLIC int sys_call(function, src_dest, m_ptr)
  1983. 07009 int function;                   /* SEND, RECEIVE, or BOTH */
  1984. 07010 int src_dest;                   /* source to receive from or dest to send to */
  1985. 07011 message *m_ptr;                 /* pointer to message */
  1986. 07012 {
  1987. 07013 /* The only system calls that exist in MINIX are sending and receiving
  1988. 07014  * messages.  These are done by trapping to the kernel with an INT instruction.
  1989. 07015  * The trap is caught and sys_call() is called to send or receive a message
  1990. 07016  * (or both). The caller is always given by proc_ptr.
  1991. 07017  */
  1992. 07018
  1993. 07019   register struct proc *rp;
  1994. 07020   int n;
  1995. 07021
  1996. 07022   /* Check for bad system call parameters. */
  1997. 07023   if (!isoksrc_dest(src_dest)) return(E_BAD_SRC);
  1998. 07024   rp = proc_ptr;
  1999. 07025
  2000. 07026   if (isuserp(rp) && function != BOTH) return(E_NO_PERM);
  2001. 07027   
  2002. 07028   /* The parameters are ok. Do the call. */
  2003. 07029   if (function & SEND) {
  2004. 07030         /* Function = SEND or BOTH. */
  2005. 07031         n = mini_send(rp, src_dest, m_ptr);
  2006. 07032         if (function == SEND || n != OK)
  2007. 07033                 return(n);      /* done, or SEND failed */
  2008. 07034   }
  2009. 07035
  2010. 07036   /* Function = RECEIVE or BOTH.
  2011. 07037    * We have checked user calls are BOTH, and trust 'function' otherwise.
  2012. 07038    */
  2013. 07039   return(mini_rec(rp, src_dest, m_ptr));
  2014. 07040 }
  2015. 07042 /*===========================================================================*
  2016. 07043  *                              mini_send                                    * 
  2017. 07044  *===========================================================================*/
  2018. 07045 PRIVATE int mini_send(caller_ptr, dest, m_ptr)
  2019. 07046 register struct proc *caller_ptr;       /* who is trying to send a message? */
  2020. 07047 int dest;                       /* to whom is message being sent? */
  2021. 07048 message *m_ptr;                 /* pointer to message buffer */
  2022. 07049 {
  2023. 07050 /* Send a message from 'caller_ptr' to 'dest'. If 'dest' is blocked waiting
  2024. 07051  * for this message, copy the message to it and unblock 'dest'. If 'dest' is
  2025. 07052  * not waiting at all, or is waiting for another source, queue 'caller_ptr'.
  2026. 07053  */
  2027. 07054
  2028. 07055   register struct proc *dest_ptr, *next_ptr;
  2029. 07056   vir_bytes vb;                 /* message buffer pointer as vir_bytes */
  2030. 07057   vir_clicks vlo, vhi;          /* virtual clicks containing message to send */
  2031. 07058
  2032. 07059   /* User processes are only allowed to send to FS and MM.  Check for this. */
  2033. 07060   if (isuserp(caller_ptr) && !issysentn(dest)) return(E_BAD_DEST);
  2034. 07061   dest_ptr = proc_addr(dest);   /* pointer to destination's proc entry */
  2035. 07062   if (dest_ptr->p_flags & P_SLOT_FREE) return(E_BAD_DEST);      /* dead dest */
  2036. 07063
  2037. 07064   /* This check allows a message to be anywhere in data or stack or gap. 
  2038. 07065    * It will have to be made more elaborate later for machines which
  2039. 07066    * don't have the gap mapped.
  2040. 07067    */
  2041. 07068   vb = (vir_bytes) m_ptr;
  2042. 07069   vlo = vb >> CLICK_SHIFT;      /* vir click for bottom of message */
  2043. 07070   vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT;    /* vir click for top of msg */
  2044. 07071   if (vlo < caller_ptr->p_map[D].mem_vir || vlo > vhi ||
  2045. 07072       vhi >= caller_ptr->p_map[S].mem_vir + caller_ptr->p_map[S].mem_len)
  2046. 07073         return(EFAULT); 
  2047. 07074
  2048. 07075   /* Check for deadlock by 'caller_ptr' and 'dest' sending to each other. */
  2049. 07076   if (dest_ptr->p_flags & SENDING) {
  2050. 07077         next_ptr = proc_addr(dest_ptr->p_sendto);
  2051. 07078         while (TRUE) {
  2052. 07079                 if (next_ptr == caller_ptr) return(ELOCKED);
  2053. 07080                 if (next_ptr->p_flags & SENDING)
  2054. 07081                         next_ptr = proc_addr(next_ptr->p_sendto);
  2055. 07082                 else
  2056. 07083                         break;
  2057. 07084         }
  2058. 07085   }
  2059. 07086
  2060. 07087   /* Check to see if 'dest' is blocked waiting for this message. */
  2061. 07088   if ( (dest_ptr->p_flags & (RECEIVING | SENDING)) == RECEIVING &&
  2062. 07089        (dest_ptr->p_getfrom == ANY ||
  2063. 07090         dest_ptr->p_getfrom == proc_number(caller_ptr))) {
  2064. 07091         /* Destination is indeed waiting for this message. */
  2065. 07092         CopyMess(proc_number(caller_ptr), caller_ptr, m_ptr, dest_ptr,
  2066. 07093                  dest_ptr->p_messbuf);
  2067. 07094         dest_ptr->p_flags &= ~RECEIVING;        /* deblock destination */
  2068. 07095         if (dest_ptr->p_flags == 0) ready(dest_ptr);
  2069. 07096   } else {
  2070. 07097         /* Destination is not waiting.  Block and queue caller. */
  2071. 07098         caller_ptr->p_messbuf = m_ptr;
  2072. 07099         if (caller_ptr->p_flags == 0) unready(caller_ptr);
  2073. 07100         caller_ptr->p_flags |= SENDING;
  2074. 07101         caller_ptr->p_sendto= dest;
  2075. 07102
  2076. 07103         /* Process is now blocked.  Put in on the destination's queue. */
  2077. 07104         if ( (next_ptr = dest_ptr->p_callerq) == NIL_PROC)
  2078. 07105                 dest_ptr->p_callerq = caller_ptr;
  2079. 07106         else {
  2080. 07107                 while (next_ptr->p_sendlink != NIL_PROC)
  2081. 07108                         next_ptr = next_ptr->p_sendlink;
  2082. 07109                 next_ptr->p_sendlink = caller_ptr;
  2083. 07110         }
  2084. 07111         caller_ptr->p_sendlink = NIL_PROC;
  2085. 07112   }
  2086. 07113   return(OK);
  2087. 07114 }
  2088. 07116 /*===========================================================================*
  2089. 07117  *                              mini_rec                                     * 
  2090. 07118  *===========================================================================*/
  2091. 07119 PRIVATE int mini_rec(caller_ptr, src, m_ptr)
  2092. 07120 register struct proc *caller_ptr;       /* process trying to get message */
  2093. 07121 int src;                        /* which message source is wanted (or ANY) */
  2094. 07122 message *m_ptr;                 /* pointer to message buffer */
  2095. 07123 {
  2096. 07124 /* A process or task wants to get a message.  If one is already queued,
  2097. 07125  * acquire it and deblock the sender.  If no message from the desired source
  2098. 07126  * is available, block the caller.  No need to check parameters for validity.
  2099. 07127  * Users calls are always sendrec(), and mini_send() has checked already.  
  2100. 07128  * Calls from the tasks, MM, and FS are trusted.
  2101. 07129  */
  2102. 07130
  2103. 07131   register struct proc *sender_ptr;
  2104. 07132   register struct proc *previous_ptr;
  2105. 07133
  2106. 07134   /* Check to see if a message from desired source is already available. */
  2107. 07135   if (!(caller_ptr->p_flags & SENDING)) {
  2108. 07136         /* Check caller queue. */
  2109. 07137     for (sender_ptr = caller_ptr->p_callerq; sender_ptr != NIL_PROC;
  2110. 07138          previous_ptr = sender_ptr, sender_ptr = sender_ptr->p_sendlink) {
  2111. 07139         if (src == ANY || src == proc_number(sender_ptr)) {
  2112. 07140                 /* An acceptable message has been found. */
  2113. 07141                 CopyMess(proc_number(sender_ptr), sender_ptr,
  2114. 07142                          sender_ptr->p_messbuf, caller_ptr, m_ptr);
  2115. 07143                 if (sender_ptr == caller_ptr->p_callerq)
  2116. 07144                         caller_ptr->p_callerq = sender_ptr->p_sendlink;
  2117. 07145                 else
  2118. 07146                         previous_ptr->p_sendlink = sender_ptr->p_sendlink;
  2119. 07147                 if ((sender_ptr->p_flags &= ~SENDING) == 0)
  2120. 07148                         ready(sender_ptr);      /* deblock sender */
  2121. 07149                 return(OK);
  2122. 07150         }
  2123. 07151     }
  2124. 07152
  2125. 07153     /* Check for blocked interrupt. */
  2126. 07154     if (caller_ptr->p_int_blocked && isrxhardware(src)) {
  2127. 07155         m_ptr->m_source = HARDWARE;
  2128. 07156         m_ptr->m_type = HARD_INT;
  2129. 07157         caller_ptr->p_int_blocked = FALSE;
  2130. 07158         return(OK);
  2131. 07159     }
  2132. 07160   }
  2133. 07161
  2134. 07162   /* No suitable message is available.  Block the process trying to receive. */
  2135. 07163   caller_ptr->p_getfrom = src;
  2136. 07164   caller_ptr->p_messbuf = m_ptr;
  2137. 07165   if (caller_ptr->p_flags == 0) unready(caller_ptr);
  2138. 07166   caller_ptr->p_flags |= RECEIVING;
  2139. 07167
  2140. 07168   /* If MM has just blocked and there are kernel signals pending, now is the
  2141. 07169    * time to tell MM about them, since it will be able to accept the message.
  2142. 07170    */
  2143. 07171   if (sig_procs > 0 && proc_number(caller_ptr) == MM_PROC_NR && src == ANY)
  2144. 07172         inform();
  2145. 07173   return(OK);
  2146. 07174 }
  2147. 07176 /*===========================================================================*
  2148. 07177  *                              pick_proc                                    * 
  2149. 07178  *===========================================================================*/
  2150. 07179 PRIVATE void pick_proc()
  2151. 07180 {
  2152. 07181 /* Decide who to run now.  A new process is selected by setting 'proc_ptr'.
  2153. 07182  * When a fresh user (or idle) process is selected, record it in 'bill_ptr',
  2154. 07183  * so the clock task can tell who to bill for system time.
  2155. 07184  */
  2156. 07185
  2157. 07186   register struct proc *rp;     /* process to run */
  2158. 07187
  2159. 07188   if ( (rp = rdy_head[TASK_Q]) != NIL_PROC) {
  2160. 07189         proc_ptr = rp;
  2161. 07190         return;
  2162. 07191   }
  2163. 07192   if ( (rp = rdy_head[SERVER_Q]) != NIL_PROC) {
  2164. 07193         proc_ptr = rp;
  2165. 07194         return;
  2166. 07195   }
  2167. 07196   if ( (rp = rdy_head[USER_Q]) != NIL_PROC) {
  2168. 07197         proc_ptr = rp;
  2169. 07198         bill_ptr = rp;
  2170. 07199         return;
  2171. 07200   }
  2172. 07201   /* No one is ready.  Run the idle task.  The idle task might be made an
  2173. 07202    * always-ready user task to avoid this special case.
  2174. 07203    */
  2175. 07204   bill_ptr = proc_ptr = proc_addr(IDLE);
  2176. 07205 }
  2177. 07207 /*===========================================================================*
  2178. 07208  *                              ready                                        * 
  2179. 07209  *===========================================================================*/
  2180. 07210 PRIVATE void ready(rp)
  2181. 07211 register struct proc *rp;       /* this process is now runnable */
  2182. 07212 {
  2183. 07213 /* Add 'rp' to the end of one of the queues of runnable processes. Three
  2184. 07214  * queues are maintained:
  2185. 07215  *   TASK_Q   - (highest priority) for runnable tasks
  2186. 07216  *   SERVER_Q - (middle priority) for MM and FS only
  2187. 07217  *   USER_Q   - (lowest priority) for user processes
  2188. 07218  */
  2189. 07219
  2190. 07220   if (istaskp(rp)) {
  2191. 07221         if (rdy_head[TASK_Q] != NIL_PROC)
  2192. 07222                 /* Add to tail of nonempty queue. */
  2193. 07223                 rdy_tail[TASK_Q]->p_nextready = rp;
  2194. 07224         else {
  2195. 07225                 proc_ptr =              /* run fresh task next */
  2196. 07226                 rdy_head[TASK_Q] = rp;  /* add to empty queue */
  2197. 07227         }
  2198. 07228         rdy_tail[TASK_Q] = rp;
  2199. 07229         rp->p_nextready = NIL_PROC;     /* new entry has no successor */
  2200. 07230         return;
  2201. 07231   }
  2202. 07232   if (!isuserp(rp)) {           /* others are similar */
  2203. 07233         if (rdy_head[SERVER_Q] != NIL_PROC)
  2204. 07234                 rdy_tail[SERVER_Q]->p_nextready = rp;
  2205. 07235         else
  2206. 07236                 rdy_head[SERVER_Q] = rp;
  2207. 07237         rdy_tail[SERVER_Q] = rp;
  2208. 07238         rp->p_nextready = NIL_PROC;
  2209. 07239         return;
  2210. 07240   }
  2211. 07241   if (rdy_head[USER_Q] == NIL_PROC)
  2212. 07242         rdy_tail[USER_Q] = rp;
  2213. 07243   rp->p_nextready = rdy_head[USER_Q];
  2214. 07244   rdy_head[USER_Q] = rp;
  2215. 07245 /*
  2216. 07246   if (rdy_head[USER_Q] != NIL_PROC)
  2217. 07247         rdy_tail[USER_Q]->p_nextready = rp;
  2218. 07248   else
  2219. 07249         rdy_head[USER_Q] = rp;
  2220. 07250   rdy_tail[USER_Q] = rp;
  2221. 07251   rp->p_nextready = NIL_PROC;
  2222. 07252 */
  2223. 07253 }
  2224. 07255 /*===========================================================================*
  2225. 07256  *                              unready                                      * 
  2226. 07257  *===========================================================================*/
  2227. 07258 PRIVATE void unready(rp)
  2228. 07259 register struct proc *rp;       /* this process is no longer runnable */
  2229. 07260 {
  2230. 07261 /* A process has blocked. */
  2231. 07262
  2232. 07263   register struct proc *xp;
  2233. 07264   register struct proc **qtail;  /* TASK_Q, SERVER_Q, or USER_Q rdy_tail */
  2234. 07265
  2235. 07266   if (istaskp(rp)) {
  2236. 07267         /* task stack still ok? */
  2237. 07268         if (*rp->p_stguard != STACK_GUARD)
  2238. 07269                 panic("stack overrun by task", proc_number(rp));
  2239. 07270
  2240. 07271         if ( (xp = rdy_head[TASK_Q]) == NIL_PROC) return;
  2241. 07272         if (xp == rp) {
  2242. 07273                 /* Remove head of queue */
  2243. 07274                 rdy_head[TASK_Q] = xp->p_nextready;
  2244. 07275                 if (rp == proc_ptr) pick_proc();
  2245. 07276                 return;
  2246. 07277         }
  2247. 07278         qtail = &rdy_tail[TASK_Q];
  2248. 07279   }
  2249. 07280   else if (!isuserp(rp)) {
  2250. 07281         if ( (xp = rdy_head[SERVER_Q]) == NIL_PROC) return;
  2251. 07282         if (xp == rp) {
  2252. 07283                 rdy_head[SERVER_Q] = xp->p_nextready;
  2253. 07284                 pick_proc();
  2254. 07285                 return;
  2255. 07286         }
  2256. 07287         qtail = &rdy_tail[SERVER_Q];
  2257. 07288   } else
  2258. 07289   {
  2259. 07290         if ( (xp = rdy_head[USER_Q]) == NIL_PROC) return;
  2260. 07291         if (xp == rp) {
  2261. 07292                 rdy_head[USER_Q] = xp->p_nextready;
  2262. 07293                 pick_proc();
  2263. 07294                 return;
  2264. 07295         }
  2265. 07296         qtail = &rdy_tail[USER_Q];
  2266. 07297   }
  2267. 07298
  2268. 07299   /* Search body of queue.  A process can be made unready even if it is
  2269. 07300    * not running by being sent a signal that kills it.
  2270. 07301    */
  2271. 07302   while (xp->p_nextready != rp)
  2272. 07303         if ( (xp = xp->p_nextready) == NIL_PROC) return;
  2273. 07304   xp->p_nextready = xp->p_nextready->p_nextready;
  2274. 07305   if (*qtail == rp) *qtail = xp;
  2275. 07306 }
  2276. 07308 /*===========================================================================*
  2277. 07309  *                              sched                                        * 
  2278. 07310  *===========================================================================*/
  2279. 07311 PRIVATE void sched()
  2280. 07312 {
  2281. 07313 /* The current process has run too long.  If another low priority (user)
  2282. 07314  * process is runnable, put the current process on the end of the user queue,
  2283. 07315  * possibly promoting another user to head of the queue.
  2284. 07316  */
  2285. 07317
  2286. 07318   if (rdy_head[USER_Q] == NIL_PROC) return;
  2287. 07319
  2288. 07320   /* One or more user processes queued. */
  2289. 07321   rdy_tail[USER_Q]->p_nextready = rdy_head[USER_Q];
  2290. 07322   rdy_tail[USER_Q] = rdy_head[USER_Q];
  2291. 07323   rdy_head[USER_Q] = rdy_head[USER_Q]->p_nextready;
  2292. 07324   rdy_tail[USER_Q]->p_nextready = NIL_PROC;
  2293. 07325   pick_proc();
  2294. 07326 }
  2295. 07328 /*==========================================================================*
  2296. 07329  *                              lock_mini_send                              *
  2297. 07330  *==========================================================================*/
  2298. 07331 PUBLIC int lock_mini_send(caller_ptr, dest, m_ptr)
  2299. 07332 struct proc *caller_ptr;        /* who is trying to send a message? */
  2300. 07333 int dest;                       /* to whom is message being sent? */
  2301. 07334 message *m_ptr;                 /* pointer to message buffer */
  2302. 07335 {
  2303. 07336 /* Safe gateway to mini_send() for tasks. */
  2304. 07337
  2305. 07338   int result;
  2306. 07339
  2307. 07340   switching = TRUE;
  2308. 07341   result = mini_send(caller_ptr, dest, m_ptr);
  2309. 07342   switching = FALSE;
  2310. 07343   return(result);
  2311. 07344 }
  2312. 07346 /*==========================================================================*
  2313. 07347  *                              lock_pick_proc                              *
  2314. 07348  *==========================================================================*/
  2315. 07349 PUBLIC void lock_pick_proc()
  2316. 07350 {
  2317. 07351 /* Safe gateway to pick_proc() for tasks. */
  2318. 07352
  2319. 07353   switching = TRUE;
  2320. 07354   pick_proc();
  2321. 07355   switching = FALSE;
  2322. 07356 }
  2323. 07358 /*==========================================================================*
  2324. 07359  *                              lock_ready                                  *
  2325. 07360  *==========================================================================*/
  2326. 07361 PUBLIC void lock_ready(rp)
  2327. 07362 struct proc *rp;                /* this process is now runnable */
  2328. 07363 {
  2329. 07364 /* Safe gateway to ready() for tasks. */
  2330. 07365
  2331. 07366   switching = TRUE;
  2332. 07367   ready(rp);
  2333. 07368   switching = FALSE;
  2334. 07369 }
  2335. 07372 /*==========================================================================*
  2336. 07373  *                              lock_unready                                *
  2337. 07374  *==========================================================================*/
  2338. 07375 PUBLIC void lock_unready(rp)
  2339. 07376 struct proc *rp;                /* this process is no longer runnable */
  2340. 07377 {
  2341. 07378 /* Safe gateway to unready() for tasks. */
  2342. 07379
  2343. 07380   switching = TRUE;
  2344. 07381   unready(rp);
  2345. 07382   switching = FALSE;
  2346. 07383 }
  2347. 07385 /*==========================================================================*
  2348. 07386  *                              lock_sched                                  *
  2349. 07387  *==========================================================================*/
  2350. 07388 PUBLIC void lock_sched()
  2351. 07389 {
  2352. 07390 /* Safe gateway to sched() for tasks. */
  2353. 07391
  2354. 07392   switching = TRUE;
  2355. 07393   sched();
  2356. 07394   switching = FALSE;
  2357. 07395 }
  2358. 07397 /*==========================================================================*
  2359. 07398  *                              unhold                                      *
  2360. 07399  *==========================================================================*/
  2361. 07400 PUBLIC void unhold()
  2362. 07401 {
  2363. 07402 /* Flush any held-up interrupts.  k_reenter must be 0.  held_head must not
  2364. 07403  * be NIL_PROC.  Interrupts must be disabled.  They will be enabled but will
  2365. 07404  * be disabled when this returns.
  2366. 07405  */
  2367. 07406
  2368. 07407   register struct proc *rp;     /* current head of held queue */
  2369. 07408
  2370. 07409   if (switching) return;
  2371. 07410   rp = held_head;
  2372. 07411   do {
  2373. 07412         if ( (held_head = rp->p_nextheld) == NIL_PROC) held_tail = NIL_PROC;
  2374. 07413         rp->p_int_held = FALSE;
  2375. 07414         unlock();               /* reduce latency; held queue may change! */
  2376. 07415         interrupt(proc_number(rp));
  2377. 07416         lock();                 /* protect the held queue again */
  2378. 07417   }
  2379. 07418   while ( (rp = held_head) != NIL_PROC);
  2380. 07419 }
  2381. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2382. src/kernel/exception.c    
  2383. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2384. 07500 /* This file contains a simple exception handler.  Exceptions in user
  2385. 07501  * processes are converted to signals.  Exceptions in the kernel, MM and
  2386. 07502  * FS cause a panic.
  2387. 07503  */
  2388. 07504
  2389. 07505 #include "kernel.h"
  2390. 07506 #include <signal.h>
  2391. 07507 #include "proc.h"
  2392. 07508
  2393. 07509 /*==========================================================================*
  2394. 07510  *                              exception                                   *
  2395. 07511  *==========================================================================*/
  2396. 07512 PUBLIC void exception(vec_nr)
  2397. 07513 unsigned vec_nr;
  2398. 07514 {
  2399. 07515 /* An exception or unexpected interrupt has occurred. */
  2400. 07516
  2401. 07517   struct ex_s {
  2402. 07518         char *msg;
  2403. 07519         int signum;
  2404. 07520         int minprocessor;
  2405. 07521   };
  2406. 07522   static struct ex_s ex_data[] = {
  2407. 07523         "Divide error", SIGFPE, 86,
  2408. 07524         "Debug exception", SIGTRAP, 86,
  2409. 07525         "Nonmaskable interrupt", SIGBUS, 86,
  2410. 07526         "Breakpoint", SIGEMT, 86,
  2411. 07527         "Overflow", SIGFPE, 86,
  2412. 07528         "Bounds check", SIGFPE, 186,
  2413. 07529         "Invalid opcode", SIGILL, 186,
  2414. 07530         "Coprocessor not available", SIGFPE, 186,
  2415. 07531         "Double fault", SIGBUS, 286,
  2416. 07532         "Copressor segment overrun", SIGSEGV, 286,
  2417. 07533         "Invalid TSS", SIGSEGV, 286,
  2418. 07534         "Segment not present", SIGSEGV, 286,
  2419. 07535         "Stack exception", SIGSEGV, 286,        /* STACK_FAULT already used */
  2420. 07536         "General protection", SIGSEGV, 286,
  2421. 07537         "Page fault", SIGSEGV, 386,             /* not close */
  2422. 07538         NIL_PTR, SIGILL, 0,                     /* probably software trap */
  2423. 07539         "Coprocessor error", SIGFPE, 386,
  2424. 07540   };
  2425. 07541   register struct ex_s *ep;
  2426. 07542   struct proc *saved_proc;
  2427. 07543
  2428. 07544   saved_proc= proc_ptr; /* Save proc_ptr, because it may be changed by debug 
  2429. 07545                          * statements.
  2430. 07546                          */
  2431. 07547
  2432. 07548   ep = &ex_data[vec_nr];
  2433. 07549
  2434. 07550   if (vec_nr == 2) {            /* spurious NMI on some machines */
  2435. 07551         printf("got spurious NMIn");
  2436. 07552         return;
  2437. 07553   }
  2438. 07554
  2439. 07555   if (k_reenter == 0 && isuserp(saved_proc)) {
  2440. 07556         unlock();               /* this is protected like sys_call() */
  2441. 07557         cause_sig(proc_number(saved_proc), ep->signum);
  2442. 07558         return;
  2443. 07559   }
  2444. 07560
  2445. 07561   /* This is not supposed to happen. */
  2446. 07562   if (ep->msg == NIL_PTR || processor < ep->minprocessor)
  2447. 07563         printf("nIntel-reserved exception %dn", vec_nr);
  2448. 07564   else
  2449. 07565         printf("n%sn", ep->msg);
  2450. 07566   printf("process number %d, pc = 0x%04x:0x%08xn",
  2451. 07567         proc_number(saved_proc),
  2452. 07568         (unsigned) saved_proc->p_reg.cs,
  2453. 07569         (unsigned) saved_proc->p_reg.pc);
  2454. 07570   panic("exception in system code", NO_NUM);
  2455. 07571 }
  2456. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2457. src/kernel/i8259.c    
  2458. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2459. 07600 /* This file contains routines for initializing the 8259 interrupt controller:
  2460. 07601  *      get_irq_handler: address of handler for a given interrupt
  2461. 07602  *      put_irq_handler: register an interrupt handler
  2462. 07603  *      intr_init:      initialize the interrupt controller(s)
  2463. 07604  */
  2464. 07605
  2465. 07606 #include "kernel.h"
  2466. 07607
  2467. 07608 #define ICW1_AT         0x11    /* edge triggered, cascade, need ICW4 */
  2468. 07609 #define ICW1_PC         0x13    /* edge triggered, no cascade, need ICW4 */
  2469. 07610 #define ICW1_PS         0x19    /* level triggered, cascade, need ICW4 */
  2470. 07611 #define ICW4_AT         0x01    /* not SFNM, not buffered, normal EOI, 8086 */
  2471. 07612 #define ICW4_PC         0x09    /* not SFNM, buffered, normal EOI, 8086 */
  2472. 07613
  2473. 07614 FORWARD _PROTOTYPE( int spurious_irq, (int irq) );
  2474. 07615
  2475. 07616 #define set_vec(nr, addr)       ((void)0) /* kluge for protected mode */
  2476. 07617
  2477. 07618 /*==========================================================================*
  2478. 07619  *                              intr_init                                   *
  2479. 07620  *==========================================================================*/
  2480. 07621 PUBLIC void intr_init(mine)
  2481. 07622 int mine;
  2482. 07623 {
  2483. 07624 /* Initialize the 8259s, finishing with all interrupts disabled.  This is
  2484. 07625  * only done in protected mode, in real mode we don't touch the 8259s, but
  2485. 07626  * use the BIOS locations instead.  The flag "mine" is set if the 8259s are
  2486. 07627  * to be programmed for Minix, or to be reset to what the BIOS expects.
  2487. 07628  */
  2488. 07629
  2489. 07630   int i;
  2490. 07631
  2491. 07632   lock();
  2492. 07633   /* The AT and newer PS/2 have two interrupt controllers, one master,
  2493. 07634    * one slaved at IRQ 2.  (We don't have to deal with the PC that
  2494. 07635    * has just one controller, because it must run in real mode.)
  2495. 07636    */
  2496. 07637   out_byte(INT_CTL, ps_mca ? ICW1_PS : ICW1_AT);
  2497. 07638   out_byte(INT_CTLMASK, mine ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
  2498. 07639                                                 /* ICW2 for master */
  2499. 07640   out_byte(INT_CTLMASK, (1 << CASCADE_IRQ));    /* ICW3 tells slaves */
  2500. 07641   out_byte(INT_CTLMASK, ICW4_AT);
  2501. 07642   out_byte(INT_CTLMASK, ~(1 << CASCADE_IRQ));   /* IRQ 0-7 mask */
  2502. 07643   out_byte(INT2_CTL, ps_mca ? ICW1_PS : ICW1_AT);
  2503. 07644   out_byte(INT2_CTLMASK, mine ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
  2504. 07645                                                 /* ICW2 for slave */
  2505. 07646   out_byte(INT2_CTLMASK, CASCADE_IRQ);          /* ICW3 is slave nr */
  2506. 07647   out_byte(INT2_CTLMASK, ICW4_AT);
  2507. 07648   out_byte(INT2_CTLMASK, ~0);                   /* IRQ 8-15 mask */
  2508. 07649
  2509. 07650   /* Initialize the table of interrupt handlers. */
  2510. 07651   for (i = 0; i < NR_IRQ_VECTORS; i++) irq_table[i] = spurious_irq;
  2511. 07652 }
  2512. 07654 /*=========================================================================*
  2513. 07655  *                              spurious_irq                               *
  2514. 07656  *=========================================================================*/
  2515. 07657 PRIVATE int spurious_irq(irq)
  2516. 07658 int irq;
  2517. 07659 {
  2518. 07660 /* Default interrupt handler.  It complains a lot. */
  2519. 07661
  2520. 07662   if (irq < 0 || irq >= NR_IRQ_VECTORS)
  2521. 07663         panic("invalid call to spurious_irq", irq);
  2522. 07664
  2523. 07665   printf("spurious irq %dn", irq);
  2524. 07666
  2525. 07667   return 1;     /* Reenable interrupt */
  2526. 07668 }
  2527. 07670 /*=========================================================================*
  2528. 07671  *                              put_irq_handler                            *
  2529. 07672  *=========================================================================*/
  2530. 07673 PUBLIC void put_irq_handler(irq, handler)
  2531. 07674 int irq;
  2532. 07675 irq_handler_t handler;
  2533. 07676 {
  2534. 07677 /* Register an interrupt handler. */
  2535. 07678
  2536. 07679   if (irq < 0 || irq >= NR_IRQ_VECTORS)
  2537. 07680         panic("invalid call to put_irq_handler", irq);
  2538. 07681
  2539. 07682   if (irq_table[irq] == handler)
  2540. 07683         return;         /* extra initialization */
  2541. 07684
  2542. 07685   if (irq_table[irq] != spurious_irq)
  2543. 07686         panic("attempt to register second irq handler for irq", irq);
  2544. 07687
  2545. 07688   disable_irq(irq);
  2546. 07689   if (!protected_mode) set_vec(BIOS_VECTOR(irq), irq_vec[irq]);
  2547. 07690   irq_table[irq]= handler;
  2548. 07691   irq_use |= 1 << irq;
  2549. 07692 }
  2550. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2551. src/kernel/protect.c    
  2552. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2553. 07700 /* This file contains code for initialization of protected mode, to initialize
  2554. 07701  * code and data segment descriptors, and to initialize global descriptors
  2555. 07702  * for local descriptors in the process table.
  2556. 07703  */
  2557. 07704
  2558. 07705 #include "kernel.h"
  2559. 07706 #include "proc.h"
  2560. 07707 #include "protect.h"
  2561. 07708
  2562. 07709 #define INT_GATE_TYPE   (INT_286_GATE | DESC_386_BIT)
  2563. 07710 #define TSS_TYPE        (AVL_286_TSS  | DESC_386_BIT)
  2564. 07711
  2565. 07712 struct desctableptr_s {
  2566. 07713   char limit[sizeof(u16_t)];
  2567. 07714   char base[sizeof(u32_t)];             /* really u24_t + pad for 286 */
  2568. 07715 };
  2569. 07716
  2570. 07717 struct gatedesc_s {
  2571. 07718   u16_t offset_low;
  2572. 07719   u16_t selector;
  2573. 07720   u8_t pad;                     /* |000|XXXXX| ig & trpg, |XXXXXXXX| task g */
  2574. 07721   u8_t p_dpl_type;              /* |P|DL|0|TYPE| */
  2575. 07722   u16_t offset_high;
  2576. 07723 };
  2577. 07724
  2578. 07725 struct tss_s {
  2579. 07726   reg_t backlink;
  2580. 07727   reg_t sp0;                    /* stack pointer to use during interrupt */
  2581. 07728   reg_t ss0;                    /*   "   segment  "  "    "        "     */
  2582. 07729   reg_t sp1;
  2583. 07730   reg_t ss1;
  2584. 07731   reg_t sp2;
  2585. 07732   reg_t ss2;
  2586. 07733   reg_t cr3;
  2587. 07734   reg_t ip;
  2588. 07735   reg_t flags;
  2589. 07736   reg_t ax;
  2590. 07737   reg_t cx;
  2591. 07738   reg_t dx;
  2592. 07739   reg_t bx;
  2593. 07740   reg_t sp;
  2594. 07741   reg_t bp;
  2595. 07742   reg_t si;
  2596. 07743   reg_t di;
  2597. 07744   reg_t es;
  2598. 07745   reg_t cs;
  2599. 07746   reg_t ss;
  2600. 07747   reg_t ds;
  2601. 07748   reg_t fs;
  2602. 07749   reg_t gs;
  2603. 07750   reg_t ldt;
  2604. 07751   u16_t trap;
  2605. 07752   u16_t iobase;
  2606. 07753 };
  2607. 07754
  2608. 07755 PUBLIC struct segdesc_s gdt[GDT_SIZE];
  2609. 07756 PRIVATE struct gatedesc_s idt[IDT_SIZE];        /* zero-init so none present */
  2610. 07757 PUBLIC struct tss_s tss;        /* zero init */
  2611. 07758
  2612. 07759 FORWARD _PROTOTYPE( void int_gate, (unsigned vec_nr, phys_bytes base,
  2613. 07760                 unsigned dpl_type) );
  2614. 07761 FORWARD _PROTOTYPE( void sdesc, (struct segdesc_s *segdp, phys_bytes base,
  2615. 07762                 phys_bytes size) );
  2616. 07763
  2617. 07764 /*=========================================================================*
  2618. 07765  *                              prot_init                                  *
  2619. 07766  *=========================================================================*/
  2620. 07767 PUBLIC void prot_init()
  2621. 07768 {
  2622. 07769 /* Set up tables for protected mode.
  2623. 07770  * All GDT slots are allocated at compile time.
  2624. 07771  */
  2625. 07772
  2626. 07773   phys_bytes code_bytes;
  2627. 07774   phys_bytes data_bytes;
  2628. 07775   struct gate_table_s *gtp;
  2629. 07776   struct desctableptr_s *dtp;
  2630. 07777   unsigned ldt_selector;
  2631. 07778   register struct proc *rp;
  2632. 07779
  2633. 07780   static struct gate_table_s {
  2634. 07781         _PROTOTYPE( void (*gate), (void) );
  2635. 07782         unsigned char vec_nr;
  2636. 07783         unsigned char privilege;
  2637. 07784   }
  2638. 07785   gate_table[] = {
  2639. 07786         divide_error, DIVIDE_VECTOR, INTR_PRIVILEGE,
  2640. 07787         single_step_exception, DEBUG_VECTOR, INTR_PRIVILEGE,
  2641. 07788         nmi, NMI_VECTOR, INTR_PRIVILEGE,
  2642. 07789         breakpoint_exception, BREAKPOINT_VECTOR, USER_PRIVILEGE,
  2643. 07790         overflow, OVERFLOW_VECTOR, USER_PRIVILEGE,
  2644. 07791         bounds_check, BOUNDS_VECTOR, INTR_PRIVILEGE,
  2645. 07792         inval_opcode, INVAL_OP_VECTOR, INTR_PRIVILEGE,
  2646. 07793         copr_not_available, COPROC_NOT_VECTOR, INTR_PRIVILEGE,
  2647. 07794         double_fault, DOUBLE_FAULT_VECTOR, INTR_PRIVILEGE,
  2648. 07795         copr_seg_overrun, COPROC_SEG_VECTOR, INTR_PRIVILEGE,
  2649. 07796         inval_tss, INVAL_TSS_VECTOR, INTR_PRIVILEGE,
  2650. 07797         segment_not_present, SEG_NOT_VECTOR, INTR_PRIVILEGE,
  2651. 07798         stack_exception, STACK_FAULT_VECTOR, INTR_PRIVILEGE,
  2652. 07799         general_protection, PROTECTION_VECTOR, INTR_PRIVILEGE,
  2653. 07800         page_fault, PAGE_FAULT_VECTOR, INTR_PRIVILEGE,
  2654. 07801         copr_error, COPROC_ERR_VECTOR, INTR_PRIVILEGE,
  2655. 07802         { hwint00, VECTOR( 0), INTR_PRIVILEGE },
  2656. 07803         { hwint01, VECTOR( 1), INTR_PRIVILEGE },
  2657. 07804         { hwint02, VECTOR( 2), INTR_PRIVILEGE },
  2658. 07805         { hwint03, VECTOR( 3), INTR_PRIVILEGE },
  2659. 07806         { hwint04, VECTOR( 4), INTR_PRIVILEGE },
  2660. 07807         { hwint05, VECTOR( 5), INTR_PRIVILEGE },
  2661. 07808         { hwint06, VECTOR( 6), INTR_PRIVILEGE },
  2662. 07809         { hwint07, VECTOR( 7), INTR_PRIVILEGE },
  2663. 07810         { hwint08, VECTOR( 8), INTR_PRIVILEGE },
  2664. 07811         { hwint09, VECTOR( 9), INTR_PRIVILEGE },
  2665. 07812         { hwint10, VECTOR(10), INTR_PRIVILEGE },
  2666. 07813         { hwint11, VECTOR(11), INTR_PRIVILEGE },
  2667. 07814         { hwint12, VECTOR(12), INTR_PRIVILEGE },
  2668. 07815         { hwint13, VECTOR(13), INTR_PRIVILEGE },
  2669. 07816         { hwint14, VECTOR(14), INTR_PRIVILEGE },
  2670. 07817         { hwint15, VECTOR(15), INTR_PRIVILEGE },
  2671. 07818   };
  2672. 07819
  2673. 07820   /* This is called early and can't use tables set up by main(). */
  2674. 07821   data_bytes = (phys_bytes) sizes[1] << CLICK_SHIFT;
  2675. 07822   if (sizes[0] == 0)
  2676. 07823         code_bytes = data_bytes;        /* common I&D */
  2677. 07824   else
  2678. 07825         code_bytes = (phys_bytes) sizes[0] << CLICK_SHIFT;
  2679. 07826
  2680. 07827   /* Build gdt and idt pointers in GDT where the BIOS expects them. */
  2681. 07828   dtp= (struct desctableptr_s *) &gdt[GDT_INDEX];
  2682. 07829   * (u16_t *) dtp->limit = (sizeof gdt) - 1;
  2683. 07830   * (u32_t *) dtp->base = vir2phys(gdt);
  2684. 07831
  2685. 07832   dtp= (struct desctableptr_s *) &gdt[IDT_INDEX];
  2686. 07833   * (u16_t *) dtp->limit = (sizeof idt) - 1;
  2687. 07834   * (u32_t *) dtp->base = vir2phys(idt);
  2688. 07835
  2689. 07836   /* Build segment descriptors for tasks and interrupt handlers. */
  2690. 07837   init_codeseg(&gdt[CS_INDEX], code_base, code_bytes, INTR_PRIVILEGE);
  2691. 07838   init_dataseg(&gdt[DS_INDEX], data_base, data_bytes, INTR_PRIVILEGE);
  2692. 07839   init_dataseg(&gdt[ES_INDEX], 0L, 0L, TASK_PRIVILEGE);
  2693. 07840
  2694. 07841   /* Build scratch descriptors for functions in klib88. */
  2695. 07842   init_dataseg(&gdt[DS_286_INDEX], (phys_bytes) 0,
  2696. 07843                (phys_bytes) MAX_286_SEG_SIZE, TASK_PRIVILEGE);
  2697. 07844   init_dataseg(&gdt[ES_286_INDEX], (phys_bytes) 0,
  2698. 07845                (phys_bytes) MAX_286_SEG_SIZE, TASK_PRIVILEGE);
  2699. 07846
  2700. 07847   /* Build local descriptors in GDT for LDT's in process table.
  2701. 07848    * The LDT's are allocated at compile time in the process table, and
  2702. 07849    * initialized whenever a process' map is initialized or changed.
  2703. 07850    */
  2704. 07851   for (rp = BEG_PROC_ADDR, ldt_selector = FIRST_LDT_INDEX * DESC_SIZE;
  2705. 07852        rp < END_PROC_ADDR; ++rp, ldt_selector += DESC_SIZE) {
  2706. 07853         init_dataseg(&gdt[ldt_selector / DESC_SIZE], vir2phys(rp->p_ldt),
  2707. 07854                      (phys_bytes) sizeof rp->p_ldt, INTR_PRIVILEGE);
  2708. 07855         gdt[ldt_selector / DESC_SIZE].access = PRESENT | LDT;
  2709. 07856         rp->p_ldt_sel = ldt_selector;
  2710. 07857   }
  2711. 07858
  2712. 07859   /* Build main TSS.
  2713. 07860    * This is used only to record the stack pointer to be used after an
  2714. 07861    * interrupt.
  2715. 07862    * The pointer is set up so that an interrupt automatically saves the
  2716. 07863    * current process's registers ip:cs:f:sp:ss in the correct slots in the
  2717. 07864    * process table.
  2718. 07865    */
  2719. 07866   tss.ss0 = DS_SELECTOR;
  2720. 07867   init_dataseg(&gdt[TSS_INDEX], vir2phys(&tss), (phys_bytes) sizeof tss,
  2721. 07868                                                         INTR_PRIVILEGE);
  2722. 07869   gdt[TSS_INDEX].access = PRESENT | (INTR_PRIVILEGE << DPL_SHIFT) | TSS_TYPE;
  2723. 07870   tss.iobase = sizeof tss;      /* empty i/o permissions map */
  2724. 07871
  2725. 07872   /* Build descriptors for interrupt gates in IDT. */
  2726. 07873   for (gtp = &gate_table[0];
  2727. 07874        gtp < &gate_table[sizeof gate_table / sizeof gate_table[0]]; ++gtp) {
  2728. 07875         int_gate(gtp->vec_nr, (phys_bytes) (vir_bytes) gtp->gate,
  2729. 07876                  PRESENT | INT_GATE_TYPE | (gtp->privilege << DPL_SHIFT));
  2730. 07877   }
  2731. 07878   int_gate(SYS_VECTOR, (phys_bytes) (vir_bytes) p_s_call,
  2732. 07879            PRESENT | (USER_PRIVILEGE << DPL_SHIFT) | INT_GATE_TYPE);
  2733. 07880   int_gate(LEVEL0_VECTOR, (phys_bytes) (vir_bytes) level0_call,
  2734. 07881            PRESENT | (TASK_PRIVILEGE << DPL_SHIFT) | INT_GATE_TYPE);
  2735. 07882   int_gate(SYS386_VECTOR, (phys_bytes) (vir_bytes) s_call,
  2736. 07883            PRESENT | (USER_PRIVILEGE << DPL_SHIFT) | INT_GATE_TYPE);
  2737. 07884 }
  2738. 07886 /*=========================================================================*
  2739. 07887  *                              init_codeseg                               *
  2740. 07888  *=========================================================================*/
  2741. 07889 PUBLIC void init_codeseg(segdp, base, size, privilege)
  2742. 07890 register struct segdesc_s *segdp;
  2743. 07891 phys_bytes base;
  2744. 07892 phys_bytes size;