device.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. /* This file is part of the program psim.
  2. Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #ifndef _DEVICE_H_
  15. #define _DEVICE_H_
  16. #ifndef INLINE_DEVICE
  17. #define INLINE_DEVICE
  18. #endif
  19. /* declared in basics.h, this object is used everywhere */
  20. /* typedef struct _device device; */
  21. /* Introduction:
  22. As explained in earlier sections, the device, device instance,
  23. property and interrupts lie at the heart of PSIM's device model.
  24. In the below a synopsis of the device object and the operations it
  25. supports are given. Details of this object can be found in the
  26. files <<device.h>> and <<device.c>>.
  27. */
  28. /* Device creation: */
  29. INLINE_DEVICE\
  30. (device *) device_create
  31. (device *parent,
  32. const char *base,
  33. const char *name,
  34. const char *unit_address,
  35. const char *args);
  36. INLINE_DEVICE\
  37. (void) device_usage
  38. (int verbose);
  39. /* Device initialization: */
  40. INLINE_DEVICE\
  41. (void) device_clean
  42. (device *root,
  43. void *data);
  44. INLINE_DEVICE\
  45. (void) device_init_static_properties
  46. (device *me,
  47. void *data);
  48. INLINE_DEVICE\
  49. (void) device_init_address
  50. (device *me,
  51. void *data);
  52. INLINE_DEVICE\
  53. (void) device_init_runtime_properties
  54. (device *me,
  55. void *data);
  56. INLINE_DEVICE\
  57. (void) device_init_data
  58. (device *me,
  59. void *data);
  60. /* Relationships:
  61. A device is able to determine its relationship to other devices
  62. within the tree. Operations include querying for a devices parent,
  63. sibling, child, name, and path (from the root).
  64. */
  65. INLINE_DEVICE\
  66. (device *) device_parent
  67. (device *me);
  68. INLINE_DEVICE\
  69. (device *) device_root
  70. (device *me);
  71. INLINE_DEVICE\
  72. (device *) device_sibling
  73. (device *me);
  74. INLINE_DEVICE\
  75. (device *) device_child
  76. (device *me);
  77. INLINE_DEVICE\
  78. (const char *) device_name
  79. (device *me);
  80. INLINE_DEVICE\
  81. (const char *) device_base
  82. (device *me);
  83. INLINE_DEVICE\
  84. (const char *) device_path
  85. (device *me);
  86. INLINE_DEVICE\
  87. (void *) device_data
  88. (device *me);
  89. INLINE_DEVICE\
  90. (psim *) device_system
  91. (device *me);
  92. typedef struct _device_unit {
  93. int nr_cells;
  94. unsigned_cell cells[4]; /* unused cells are zero */
  95. } device_unit;
  96. INLINE_DEVICE\
  97. (const device_unit *) device_unit_address
  98. (device *me);
  99. INLINE_DEVICE\
  100. (int) device_decode_unit
  101. (device *bus,
  102. const char *unit,
  103. device_unit *address);
  104. INLINE_DEVICE\
  105. (int) device_encode_unit
  106. (device *bus,
  107. const device_unit *unit_address,
  108. char *buf,
  109. int sizeof_buf);
  110. /* Convert an Open Firmware size into a form suitable for attach
  111. address calls.
  112. Return a zero result if the address should be ignored when looking
  113. for attach addresses */
  114. INLINE_DEVICE\
  115. (int) device_address_to_attach_address
  116. (device *me,
  117. const device_unit *address,
  118. int *attach_space,
  119. unsigned_word *attach_address,
  120. device *client);
  121. /* Convert an Open Firmware size into a form suitable for attach
  122. address calls
  123. Return a zero result if the address should be ignored */
  124. INLINE_DEVICE\
  125. (int) device_size_to_attach_size
  126. (device *me,
  127. const device_unit *size,
  128. unsigned *nr_bytes,
  129. device *client);
  130. INLINE_DEVICE\
  131. (unsigned) device_nr_address_cells
  132. (device *me);
  133. INLINE_DEVICE\
  134. (unsigned) device_nr_size_cells
  135. (device *me);
  136. /* Properties:
  137. Attached to a device are a number of properties. Each property has
  138. a size and type (both of which can be queried). A device is able
  139. to iterate over or query and set a properties value.
  140. */
  141. /* The following are valid property types. The property `array' is
  142. for generic untyped data. */
  143. typedef enum {
  144. array_property,
  145. boolean_property,
  146. ihandle_property, /*runtime*/
  147. integer_property,
  148. range_array_property,
  149. reg_array_property,
  150. string_property,
  151. string_array_property,
  152. } device_property_type;
  153. typedef struct _device_property device_property;
  154. struct _device_property {
  155. device *owner;
  156. const char *name;
  157. device_property_type type;
  158. unsigned sizeof_array;
  159. const void *array;
  160. const device_property *original;
  161. object_disposition disposition;
  162. };
  163. /* iterate through the properties attached to a device */
  164. INLINE_DEVICE\
  165. (const device_property *) device_next_property
  166. (const device_property *previous);
  167. INLINE_DEVICE\
  168. (const device_property *) device_find_property
  169. (device *me,
  170. const char *property); /* NULL for first property */
  171. /* Manipulate the properties belonging to a given device.
  172. SET on the other hand will force the properties value. The
  173. simulation is aborted if the property was present but of a
  174. conflicting type.
  175. FIND returns the specified properties value, aborting the
  176. simulation if the property is missing. Code locating a property
  177. should first check its type (using device_find_property above) and
  178. then obtain its value using the below.
  179. void device_add_<type>_property(device *, const char *, <type>)
  180. void device_add_*_array_property(device *, const char *, const <type>*, int)
  181. void device_set_*_property(device *, const char *, <type>)
  182. void device_set_*_array_property(device *, const char *, const <type>*, int)
  183. <type> device_find_*_property(device *, const char *)
  184. int device_find_*_array_property(device *, const char *, int, <type>*)
  185. */
  186. INLINE_DEVICE\
  187. (void) device_add_array_property
  188. (device *me,
  189. const char *property,
  190. const void *array,
  191. int sizeof_array);
  192. INLINE_DEVICE\
  193. (void) device_set_array_property
  194. (device *me,
  195. const char *property,
  196. const void *array,
  197. int sizeof_array);
  198. INLINE_DEVICE\
  199. (const device_property *) device_find_array_property
  200. (device *me,
  201. const char *property);
  202. INLINE_DEVICE\
  203. (void) device_add_boolean_property
  204. (device *me,
  205. const char *property,
  206. int boolean);
  207. INLINE_DEVICE\
  208. (int) device_find_boolean_property
  209. (device *me,
  210. const char *property);
  211. typedef struct _ihandle_runtime_property_spec {
  212. const char *full_path;
  213. } ihandle_runtime_property_spec;
  214. INLINE_DEVICE\
  215. (void) device_add_ihandle_runtime_property
  216. (device *me,
  217. const char *property,
  218. const ihandle_runtime_property_spec *ihandle);
  219. INLINE_DEVICE\
  220. (void) device_find_ihandle_runtime_property
  221. (device *me,
  222. const char *property,
  223. ihandle_runtime_property_spec *ihandle);
  224. INLINE_DEVICE\
  225. (void) device_set_ihandle_property
  226. (device *me,
  227. const char *property,
  228. device_instance *ihandle);
  229. INLINE_DEVICE\
  230. (device_instance *) device_find_ihandle_property
  231. (device *me,
  232. const char *property);
  233. INLINE_DEVICE\
  234. (void) device_add_integer_property
  235. (device *me,
  236. const char *property,
  237. signed_cell integer);
  238. INLINE_DEVICE\
  239. (signed_cell) device_find_integer_property
  240. (device *me,
  241. const char *property);
  242. INLINE_DEVICE\
  243. (int) device_find_integer_array_property
  244. (device *me,
  245. const char *property,
  246. unsigned index,
  247. signed_cell *integer);
  248. typedef struct _range_property_spec {
  249. device_unit child_address;
  250. device_unit parent_address;
  251. device_unit size;
  252. } range_property_spec;
  253. INLINE_DEVICE\
  254. (void) device_add_range_array_property
  255. (device *me,
  256. const char *property,
  257. const range_property_spec *ranges,
  258. unsigned nr_ranges);
  259. INLINE_DEVICE\
  260. (int) device_find_range_array_property
  261. (device *me,
  262. const char *property,
  263. unsigned index,
  264. range_property_spec *range);
  265. typedef struct _reg_property_spec {
  266. device_unit address;
  267. device_unit size;
  268. } reg_property_spec;
  269. INLINE_DEVICE\
  270. (void) device_add_reg_array_property
  271. (device *me,
  272. const char *property,
  273. const reg_property_spec *reg,
  274. unsigned nr_regs);
  275. INLINE_DEVICE\
  276. (int) device_find_reg_array_property
  277. (device *me,
  278. const char *property,
  279. unsigned index,
  280. reg_property_spec *reg);
  281. INLINE_DEVICE\
  282. (void) device_add_string_property
  283. (device *me,
  284. const char *property,
  285. const char *string);
  286. INLINE_DEVICE\
  287. (const char *) device_find_string_property
  288. (device *me,
  289. const char *property);
  290. typedef const char *string_property_spec;
  291. INLINE_DEVICE\
  292. (void) device_add_string_array_property
  293. (device *me,
  294. const char *property,
  295. const string_property_spec *strings,
  296. unsigned nr_strings);
  297. INLINE_DEVICE\
  298. (int) device_find_string_array_property
  299. (device *me,
  300. const char *property,
  301. unsigned index,
  302. string_property_spec *string);
  303. INLINE_DEVICE\
  304. (void) device_add_duplicate_property
  305. (device *me,
  306. const char *property,
  307. const device_property *original);
  308. /* Instances:
  309. As with IEEE1275, a device can be opened, creating an instance.
  310. Instances provide more abstract interfaces to the underlying
  311. hardware. For example, the instance methods for a disk may include
  312. code that is able to interpret file systems found on disks. Such
  313. methods would there for allow the manipulation of files on the
  314. disks file system. The operations would be implemented using the
  315. basic block I/O model provided by the disk.
  316. This model includes methods that faciliate the creation of device
  317. instance and (should a given device support it) standard operations
  318. on those instances.
  319. */
  320. typedef struct _device_instance_callbacks device_instance_callbacks;
  321. INLINE_DEVICE\
  322. (device_instance *) device_create_instance_from
  323. (device *me, /*OR*/ device_instance *parent,
  324. void *data,
  325. const char *path,
  326. const char *args,
  327. const device_instance_callbacks *callbacks);
  328. INLINE_DEVICE\
  329. (device_instance *) device_create_instance
  330. (device *me,
  331. const char *full_path,
  332. const char *args);
  333. INLINE_DEVICE\
  334. (void) device_instance_delete
  335. (device_instance *instance);
  336. INLINE_DEVICE\
  337. (int) device_instance_read
  338. (device_instance *instance,
  339. void *addr,
  340. unsigned_word len);
  341. INLINE_DEVICE\
  342. (int) device_instance_write
  343. (device_instance *instance,
  344. const void *addr,
  345. unsigned_word len);
  346. INLINE_DEVICE\
  347. (int) device_instance_seek
  348. (device_instance *instance,
  349. unsigned_word pos_hi,
  350. unsigned_word pos_lo);
  351. INLINE_DEVICE\
  352. (int) device_instance_call_method
  353. (device_instance *instance,
  354. const char *method,
  355. int n_stack_args,
  356. unsigned_cell stack_args[/*n_stack_args*/],
  357. int n_stack_returns,
  358. unsigned_cell stack_returns[/*n_stack_returns*/]);
  359. INLINE_DEVICE\
  360. (device *) device_instance_device
  361. (device_instance *instance);
  362. INLINE_DEVICE\
  363. (const char *) device_instance_path
  364. (device_instance *instance);
  365. INLINE_DEVICE\
  366. (void *) device_instance_data
  367. (device_instance *instance);
  368. /* Interrupts:
  369. */
  370. /* Interrupt Source
  371. A device drives its interrupt line using the call
  372. */
  373. INLINE_DEVICE\
  374. (void) device_interrupt_event
  375. (device *me,
  376. int my_port,
  377. int value,
  378. cpu *processor,
  379. unsigned_word cia);
  380. /* This interrupt event will then be propogated to any attached
  381. interrupt destinations.
  382. Any interpretation of PORT and VALUE is model dependant. However
  383. as guidelines the following are recommended: PCI interrupts a-d
  384. correspond to lines 0-3; level sensative interrupts be requested
  385. with a value of one and withdrawn with a value of 0; edge sensative
  386. interrupts always have a value of 1, the event its self is treated
  387. as the interrupt.
  388. Interrupt Destinations
  389. Attached to each interrupt line of a device can be zero or more
  390. desitinations. These destinations consist of a device/port pair.
  391. A destination is attached/detached to a device line using the
  392. attach and detach calls. */
  393. INLINE_DEVICE\
  394. (void) device_interrupt_attach
  395. (device *me,
  396. int my_port,
  397. device *dest,
  398. int dest_port,
  399. object_disposition disposition);
  400. INLINE_DEVICE\
  401. (void) device_interrupt_detach
  402. (device *me,
  403. int my_port,
  404. device *dest,
  405. int dest_port);
  406. typedef void (device_interrupt_traverse_function)
  407. (device *me,
  408. int my_port,
  409. device *dest,
  410. int my_dest,
  411. void *data);
  412. INLINE_DEVICE\
  413. (void) device_interrupt_traverse
  414. (device *me,
  415. device_interrupt_traverse_function *handler,
  416. void *data);
  417. /* DESTINATION is attached (detached) to LINE of the device ME
  418. Interrupt conversion
  419. Users refer to interrupt port numbers symbolically. For instance a
  420. device may refer to its `INT' signal which is internally
  421. represented by port 3.
  422. To convert to/from the symbolic and internal representation of a
  423. port name/number. The following functions are available. */
  424. INLINE_DEVICE\
  425. (int) device_interrupt_decode
  426. (device *me,
  427. const char *symbolic_name,
  428. port_direction direction);
  429. INLINE_DEVICE\
  430. (int) device_interrupt_encode
  431. (device *me,
  432. int port_number,
  433. char *buf,
  434. int sizeof_buf,
  435. port_direction direction);
  436. /* Hardware operations:
  437. */
  438. INLINE_DEVICE\
  439. (unsigned) device_io_read_buffer
  440. (device *me,
  441. void *dest,
  442. int space,
  443. unsigned_word addr,
  444. unsigned nr_bytes,
  445. cpu *processor,
  446. unsigned_word cia);
  447. INLINE_DEVICE\
  448. (unsigned) device_io_write_buffer
  449. (device *me,
  450. const void *source,
  451. int space,
  452. unsigned_word addr,
  453. unsigned nr_bytes,
  454. cpu *processor,
  455. unsigned_word cia);
  456. /* Conversly, the device pci1000,1@1 my need to perform a dma transfer
  457. into the cpu/memory core. Just as I/O moves towards the leaves,
  458. dma transfers move towards the core via the initiating devices
  459. parent nodes. The root device (special) converts the DMA transfer
  460. into reads/writes to memory */
  461. INLINE_DEVICE\
  462. (unsigned) device_dma_read_buffer
  463. (device *me,
  464. void *dest,
  465. int space,
  466. unsigned_word addr,
  467. unsigned nr_bytes);
  468. INLINE_DEVICE\
  469. (unsigned) device_dma_write_buffer
  470. (device *me,
  471. const void *source,
  472. int space,
  473. unsigned_word addr,
  474. unsigned nr_bytes,
  475. int violate_read_only_section);
  476. /* To avoid the need for an intermediate (bridging) node to ask each
  477. of its child devices in turn if an IO access is intended for them,
  478. parent nodes maintain a table mapping addresses directly to
  479. specific devices. When a device is `connected' to its bus it
  480. attaches its self to its parent. */
  481. /* Address access attributes */
  482. typedef enum _access_type {
  483. access_invalid = 0,
  484. access_read = 1,
  485. access_write = 2,
  486. access_read_write = 3,
  487. access_exec = 4,
  488. access_read_exec = 5,
  489. access_write_exec = 6,
  490. access_read_write_exec = 7,
  491. } access_type;
  492. /* Address attachement types */
  493. typedef enum _attach_type {
  494. attach_invalid,
  495. attach_raw_memory,
  496. attach_callback,
  497. /* ... */
  498. } attach_type;
  499. INLINE_DEVICE\
  500. (void) device_attach_address
  501. (device *me,
  502. attach_type attach,
  503. int space,
  504. unsigned_word addr,
  505. unsigned nr_bytes,
  506. access_type access,
  507. device *client); /*callback/default*/
  508. INLINE_DEVICE\
  509. (void) device_detach_address
  510. (device *me,
  511. attach_type attach,
  512. int space,
  513. unsigned_word addr,
  514. unsigned nr_bytes,
  515. access_type access,
  516. device *client); /*callback/default*/
  517. /* Utilities:
  518. */
  519. /* IOCTL::
  520. Often devices require `out of band' operations to be performed.
  521. For instance a pal device may need to notify a PCI bridge device
  522. that an interrupt ack cycle needs to be performed on the PCI bus.
  523. Within PSIM such operations are performed by using the generic
  524. ioctl call <<device_ioctl()>>.
  525. */
  526. typedef enum {
  527. device_ioctl_break, /* unsigned_word requested_break */
  528. device_ioctl_set_trace, /* void */
  529. device_ioctl_create_stack, /* unsigned_word *sp, char **argv, char **envp */
  530. device_ioctl_change_media, /* const char *new_image (possibly NULL) */
  531. nr_device_ioctl_requests,
  532. } device_ioctl_request;
  533. EXTERN_DEVICE\
  534. (int) device_ioctl
  535. (device *me,
  536. cpu *processor,
  537. unsigned_word cia,
  538. device_ioctl_request request,
  539. ...);
  540. /* Error reporting::
  541. So that errors originating from devices appear in a consistent
  542. format, the <<device_error()>> function can be used. Formats and
  543. outputs the error message before aborting the simulation
  544. Devices should use this function to abort the simulation except
  545. when the abort reason leaves the simulation in a hazardous
  546. condition (for instance a failed malloc).
  547. */
  548. EXTERN_DEVICE\
  549. (void) device_error
  550. (device *me,
  551. const char *fmt,
  552. ...) ATTRIBUTE_PRINTF_2;
  553. INLINE_DEVICE\
  554. (int) device_trace
  555. (device *me);
  556. /* External representation:
  557. Both device nodes and device instances, in OpenBoot firmware have
  558. an external representation (phandles and ihandles) and these values
  559. are both stored in the device tree in property nodes and passed
  560. between the client program and the simulator during emulation
  561. calls.
  562. To limit the potential risk associated with trusing `data' from the
  563. client program, the following mapping operators `safely' convert
  564. between the two representations
  565. */
  566. INLINE_DEVICE\
  567. (device *) external_to_device
  568. (device *tree_member,
  569. unsigned_cell phandle);
  570. INLINE_DEVICE\
  571. (unsigned_cell) device_to_external
  572. (device *me);
  573. INLINE_DEVICE\
  574. (device_instance *) external_to_device_instance
  575. (device *tree_member,
  576. unsigned_cell ihandle);
  577. INLINE_DEVICE\
  578. (unsigned_cell) device_instance_to_external
  579. (device_instance *me);
  580. /* Event queue:
  581. The device inherets certain event queue operations from the main
  582. simulation. */
  583. typedef void device_event_handler(void *data);
  584. INLINE_DEVICE\
  585. (event_entry_tag) device_event_queue_schedule
  586. (device *me,
  587. int64_t delta_time,
  588. device_event_handler *handler,
  589. void *data);
  590. INLINE_DEVICE\
  591. (void) device_event_queue_deschedule
  592. (device *me,
  593. event_entry_tag event_to_remove);
  594. INLINE_DEVICE\
  595. (int64_t) device_event_queue_time
  596. (device *me);
  597. #endif /* _DEVICE_H_ */