4
* Implementation of System manager.
6
* Copyright (C) 2009 Texas Instruments, Inc.
8
* This package is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License version 2 as
10
* published by the Free Software Foundation.
12
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
19
/* Standard headers */
20
#include <linux/types.h>
21
#include <linux/module.h>
23
#include <syslink/atomic_linux.h>
26
#include <multiproc.h>
27
#include <sysmemmgr.h>
31
#include <platform_mem.h>
33
#include <gatepeterson.h>
34
#include <sharedregion.h>
37
#include <messageq_transportshm.h>
39
/*#include <notify_driver.h>*/
40
#include <notify_ducatidriver.h>
42
#include <nameserver.h>
43
#include <nameserver_remote.h>
44
#include <nameserver_remotenotify.h>
49
/* =============================================================================
51
* =============================================================================
54
* @def BOOTLOADPAGESIZE
55
* @brief Error code base for System manager.
57
#define BOOTLOADPAGESIZE (0x1000) /* 4K page size */
60
* @def SYSMGR_ENTRYVALIDITYSTAMP
61
* @brief Validity stamp for boot load page entries.
63
#define SYSMGR_ENTRYVALIDITYSTAMP (0xBABAC0C0)
66
* @def SYSMGR_ENTRYVALIDSTAMP
67
* @brief Validity stamp for boot load page entries.
69
#define SYSMGR_ENTRYVALIDSTAMP (0xBABAC0C0)
72
* @def SYSMGR_SCALABILITYHANDSHAKESTAMP
73
* @brief scalability configuration handshake value.
75
#define SYSMGR_SCALABILITYHANDSHAKESTAMP (0xBEEF0000)
78
* @def SYSMGR_SETUPHANDSHAKESTAMP
79
* @brief Platform configured handshake value.
81
#define SYSMGR_SETUPHANDSHAKESTAMP (0xBEEF0001)
84
* @def SYSMGR_DESTROYHANDSHAKESTAMP
85
* @brief Destroy handshake value.
87
#define SYSMGR_DESTROYHANDSHAKESTAMP (0xBEEF0002)
90
* @def SYSMGR_BOOTLOADPAGESIZE
91
* @brief Boot load page size.
93
#define SYSMGR_BOOTLOADPAGESIZE (0x00001000)
95
/* Macro to make a correct module magic number with ref_count */
96
#define SYSMGR_MAKE_MAGICSTAMP(x) ((SYSMGR_MODULEID << 12) | (x))
99
/* =============================================================================
101
* =============================================================================
103
/*! @brief structure for System manager boot load page entry */
104
struct sysmgr_bootload_page_entry {
106
/* Offset of next entry (-1 if not present) */
108
/* Validity of the entry */
110
/* Size of the entry data */
115
/*! @brief structure containg system manager state object */
116
struct sysmgr_boot_load_page {
117
VOLATILE struct sysmgr_bootload_page_entry host_config;
118
/* First entry, host specific configuration in the boot load page */
119
u8 padding1[(BOOTLOADPAGESIZE/2) - \
120
sizeof(struct sysmgr_bootload_page_entry)];
122
VOLATILE u32 handshake;
123
/* Handshake variable, wrote by slave to indicate configuration done. */
124
VOLATILE struct sysmgr_bootload_page_entry slave_config;
125
/* First entry, slave specific configuration in the boot load page */
126
u8 padding2[(BOOTLOADPAGESIZE/2) - \
127
sizeof(struct sysmgr_bootload_page_entry) - \
132
/*! @brief structure for System manager module state */
133
struct sysmgr_module_object {
135
/* Reference count */
136
struct sysmgr_config config;
137
/* Overall system configuration */
138
struct sysmgr_boot_load_page *boot_load_page[MULTIPROC_MAXPROCESSORS];
139
/* Boot load page of the slaves */
140
bool platform_mem_init_flag;
141
/* Platform memory manager initialize flag */
142
bool multiproc_init_flag;
143
/* Multiproc Initialize flag */
144
bool gatepeterson_init_flag;
145
/* Gatepeterson Initialize flag */
146
bool sharedregion_init_flag;
147
/* Sharedregion Initialize flag */
148
bool listmp_init_flag;
149
/* Listmp Initialize flag */
150
bool messageq_init_flag;
151
/* Messageq Initialize flag */
152
bool notify_init_flag;
153
/* Notify Initialize flag */
154
bool proc_mgr_init_flag;
155
/* Processor manager Initialize flag */
156
bool heapbuf_init_flag;
157
/* Heapbuf Initialize flag */
158
bool nameserver_init_flag;
159
/* Nameserver_remotenotify Initialize flag */
160
bool listmp_sharedmemory_init_flag;
161
/* Listmp_sharedmemory Initialize flag */
162
bool messageq_transportshm_init_flag;
163
/* Messageq_transportshm Initialize flag */
164
bool notify_ducatidrv_init_flag;
165
/* notify_ducatidrv Initialize flag */
166
bool nameserver_remotenotify_init_flag;
167
/* nameserver_remotenotify Initialize flag */
168
bool platform_init_flag;
169
/* Flag to indicate platform initialization status */
173
/* =============================================================================
175
* =============================================================================
180
* @brief Variable holding state of system manager.
182
static struct sysmgr_module_object sysmgr_state;
185
/* =============================================================================
187
* =============================================================================
190
* ======== sysmgr_get_config ========
192
* Function to get the default values for configuration.
194
void sysmgr_get_config(struct sysmgr_config *config)
198
if (WARN_ON(config == NULL)) {
200
pr_err("sysmgr_get_config [0x%x] : Argument of type"
201
" (sysmgr_get_config *) passed is null!",
206
/* Get the gatepeterson default config */
207
multiproc_get_config(&config->multiproc_cfg);
209
/* Get the gatepeterson default config */
210
gatepeterson_get_config(&config->gatepeterson_cfg);
212
/* Get the sharedregion default config */
213
sharedregion_get_config(&config->sharedregion_cfg);
215
/* Get the messageq default config */
216
messageq_get_config(&config->messageq_cfg);
218
/* Get the notify default config */
219
notify_get_config(&config->notify_cfg);
221
/* Get the proc_mgr default config */
222
proc_mgr_get_config(&config->proc_mgr_cfg);
224
/* Get the heapbuf default config */
225
heapbuf_get_config(&config->heapbuf_cfg);
227
/* Get the listmp_sharedmemory default config */
228
listmp_sharedmemory_get_config(&config->listmp_sharedmemory_cfg);
230
/* Get the messageq_transportshm default config */
231
messageq_transportshm_get_config(&config->messageq_transportshm_cfg);
233
/* Get the notify_ducati driver default config */
234
notify_ducatidrv_getconfig(&config->notify_ducatidrv_cfg);
236
/* Get the nameserver_remotenotify default config */
237
nameserver_remotenotify_get_config(
238
&config->nameserver_remotenotify_cfg);
240
EXPORT_SYMBOL(sysmgr_get_config);
243
* ======== sysmgr_get_object_config ========
245
* Function to get the SysMgr Object configuration from Slave.
247
u32 sysmgr_get_object_config(u16 proc_id, void *config, u32 cmd_id, u32 size)
249
struct sysmgr_bootload_page_entry *entry = NULL;
252
struct sysmgr_boot_load_page *blp = NULL;
254
if ((proc_id < 0) || (proc_id >= MULTIPROC_MAXPROCESSORS)) {
259
blp = (struct sysmgr_boot_load_page *)
260
sysmgr_state.boot_load_page[proc_id];
262
entry = (struct sysmgr_bootload_page_entry *) &blp->slave_config;
263
while (entry->valid == SYSMGR_ENTRYVALIDSTAMP) {
264
if (entry->cmd_id == cmd_id) {
265
if (size == entry->size) {
266
memcpy(config, (void *)((u32)entry + \
267
sizeof(struct sysmgr_bootload_page_entry)),
273
if (entry->offset != -1) {
274
offset += entry->offset;
275
entry = (struct sysmgr_bootload_page_entry *)
276
((u32) &blp->slave_config + entry->offset);
283
/* return number of bytes wrote to the boot load page */
289
* ======== sysmgr_put_object_config ========
291
* Function to put the SysMgr Object configuration to Slave.
293
u32 sysmgr_put_object_config(u16 proc_id, void *config, u32 cmd_id, u32 size)
295
struct sysmgr_bootload_page_entry *entry = NULL;
296
struct sysmgr_bootload_page_entry *prev = NULL;
298
struct sysmgr_boot_load_page *blp = NULL;
300
if ((proc_id < 0) || (proc_id >= MULTIPROC_MAXPROCESSORS)) {
305
/* Get the boot load page pointer */
306
blp = sysmgr_state.boot_load_page[proc_id];
308
/* Put the entry at the end of list */
309
entry = (struct sysmgr_bootload_page_entry *) &blp->host_config;
310
while (entry->valid == SYSMGR_ENTRYVALIDSTAMP) {
312
if (entry->offset != -1) {
313
offset += entry->offset;
314
entry = (struct sysmgr_bootload_page_entry *)
315
((u32) &blp->host_config + entry->offset);
321
/* First entry has prev set to NULL */
324
entry->cmd_id = cmd_id;
326
memcpy((void *)((u32)entry + \
327
sizeof(struct sysmgr_bootload_page_entry)),
329
entry->valid = SYSMGR_ENTRYVALIDSTAMP;
331
entry = (struct sysmgr_bootload_page_entry *)((u32)entry + \
332
sizeof(struct sysmgr_bootload_page_entry) + \
335
entry->cmd_id = cmd_id;
337
memcpy((void *)((u32)entry + \
338
sizeof(struct sysmgr_bootload_page_entry)),
340
entry->valid = SYSMGR_ENTRYVALIDSTAMP;
342
/* Attach the new created entry */
343
prev->offset = ((u32) entry - (u32) &blp->host_config);
347
/* return number of bytes wrote to the boot load page */
353
* ======== sysmgr_setup ========
355
* Function to setup the System.
357
s32 sysmgr_setup(const struct sysmgr_config *cfg)
360
struct sysmgr_config *config = NULL;
362
/* This sets the ref_count variable is not initialized, upper 16 bits is
363
* written with module Id to ensure correctness of ref_count variable.
365
atomic_cmpmask_and_set(&sysmgr_state.ref_count,
366
SYSMGR_MAKE_MAGICSTAMP(0),
367
SYSMGR_MAKE_MAGICSTAMP(0));
369
if (atomic_inc_return(&sysmgr_state.ref_count)
370
!= SYSMGR_MAKE_MAGICSTAMP(1)) {
376
sysmgr_get_config(&sysmgr_state.config);
377
config = &sysmgr_state.config;
379
memcpy((void *) (&sysmgr_state.config), (void *) cfg,
380
sizeof(struct sysmgr_config));
381
config = (struct sysmgr_config *) cfg;
384
/* Initialize PlatformMem */
385
status = platform_mem_setup();
387
pr_err("sysmgr_setup : platform_mem_setup "
388
"failed [0x%x]\n", status);
390
pr_err("platform_mem_setup : status [0x%x]\n" ,
392
sysmgr_state.platform_mem_init_flag = true;
395
/* Override the platform specific configuration */
396
platform_override_config(config);
398
status = multiproc_setup(&(config->multiproc_cfg));
400
pr_err("sysmgr_setup : multiproc_setup "
401
"failed [0x%x]\n", status);
403
pr_err("sysmgr_setup : status [0x%x]\n" , status);
404
sysmgr_state.multiproc_init_flag = true;
407
/* Initialize ProcMgr */
409
status = proc_mgr_setup(&(config->proc_mgr_cfg));
411
pr_err("sysmgr_setup : proc_mgr_setup "
412
"failed [0x%x]\n", status);
414
pr_err("proc_mgr_setup : status [0x%x]\n" ,
416
sysmgr_state.proc_mgr_init_flag = true;
420
/* Initialize SharedRegion */
422
status = sharedregion_setup(&config->sharedregion_cfg);
424
pr_err("sysmgr_setup : sharedregion_setup "
425
"failed [0x%x]\n", status);
427
pr_err("sharedregion_setup : status [0x%x]\n" ,
429
sysmgr_state.sharedregion_init_flag = true;
433
/* Initialize Notify */
435
status = notify_setup(&config->notify_cfg);
437
pr_err("sysmgr_setup : notify_setup "
438
"failed [0x%x]\n", status);
440
pr_err("notify_setup : status [0x%x]\n" ,
442
sysmgr_state.notify_init_flag = true;
446
/* Initialize NameServer */
448
status = nameserver_setup();
450
pr_err("sysmgr_setup : nameserver_setup "
451
"failed [0x%x]\n", status);
453
pr_err("nameserver_setup : status [0x%x]\n" ,
455
sysmgr_state.nameserver_init_flag = true;
459
/* Initialize GatePeterson */
461
status = gatepeterson_setup(&config->gatepeterson_cfg);
463
pr_err("sysmgr_setup : gatepeterson_setup "
464
"failed [0x%x]\n", status);
466
pr_err("gatepeterson_setup : status [0x%x]\n" ,
468
sysmgr_state.gatepeterson_init_flag = true;
472
/* Intialize MessageQ */
474
status = messageq_setup(&config->messageq_cfg);
476
pr_err("sysmgr_setup : messageq_setup "
477
"failed [0x%x]\n", status);
479
pr_err("messageq_setup : status [0x%x]\n" ,
481
sysmgr_state.messageq_init_flag = true;
485
/* Intialize HeapBuf */
487
status = heapbuf_setup(&config->heapbuf_cfg);
489
pr_err("sysmgr_setup : heapbuf_setup "
490
"failed [0x%x]\n", status);
492
pr_err("heapbuf_setup : status [0x%x]\n" ,
494
sysmgr_state.heapbuf_init_flag = true;
498
/* Initialize ListMPSharedMemory */
500
status = listmp_sharedmemory_setup(
501
&config->listmp_sharedmemory_cfg);
503
pr_err("sysmgr_setup : "
504
"listmp_sharedmemory_setup failed [0x%x]\n",
507
pr_err("listmp_sharedmemory_setup : "
508
"status [0x%x]\n" , status);
509
sysmgr_state.listmp_sharedmemory_init_flag = true;
513
/* Initialize MessageQTransportShm */
515
status = messageq_transportshm_setup(
516
&config->messageq_transportshm_cfg);
518
pr_err("sysmgr_setup : "
519
"messageq_transportshm_setup failed [0x%x]\n",
522
pr_err("messageq_transportshm_setup : "
523
"status [0x%x]\n", status);
524
sysmgr_state.messageq_transportshm_init_flag = true;
528
/* Initialize Notify DucatiDriver */
530
status = notify_ducatidrv_setup(&config->notify_ducatidrv_cfg);
532
pr_err("sysmgr_setup : "
533
"notify_ducatidrv_setup failed [0x%x]\n",
536
pr_err("notify_ducatidrv_setup : "
537
"status [0x%x]\n" , status);
538
sysmgr_state.notify_ducatidrv_init_flag = true;
542
/* Initialize NameServerRemoteNotify */
544
status = nameserver_remotenotify_setup(
545
&config->nameserver_remotenotify_cfg);
547
pr_err("sysmgr_setup : "
548
"nameserver_remotenotify_setup failed [0x%x]\n",
551
pr_err("nameserver_remotenotify_setup : "
552
"status [0x%x]\n" , status);
553
sysmgr_state.nameserver_remotenotify_init_flag = true;
558
/* Call platform setup function */
559
status = platform_setup(config);
561
pr_err("sysmgr_setup : platform_setup "
562
"failed [0x%x]\n", status);
564
pr_err("platform_setup : status [0x%x]\n" ,
566
sysmgr_state.platform_init_flag = true;
572
atomic_set(&sysmgr_state.ref_count, SYSMGR_MAKE_MAGICSTAMP(0));
576
EXPORT_SYMBOL(sysmgr_setup);
579
* ======== sysmgr_setup ========
581
* Function to finalize the System.
583
s32 sysmgr_destroy(void)
587
if (atomic_cmpmask_and_lt(&(sysmgr_state.ref_count),
588
SYSMGR_MAKE_MAGICSTAMP(0),
589
SYSMGR_MAKE_MAGICSTAMP(1)) != false) {
590
/*! @retval SYSMGR_E_INVALIDSTATE Module was not initialized */
591
status = SYSMGR_E_INVALIDSTATE;
595
if (atomic_dec_return(&sysmgr_state.ref_count)
596
!= SYSMGR_MAKE_MAGICSTAMP(0)) {
601
/* Finalize Platform module*/
602
if (sysmgr_state.platform_init_flag == true) {
603
status = platform_destroy();
605
pr_err("sysmgr_destroy : platform_destroy "
606
"failed [0x%x]\n", status);
608
sysmgr_state.platform_init_flag = false;
612
/* Finalize NameServerRemoteNotify module */
613
if (sysmgr_state.nameserver_remotenotify_init_flag == true) {
614
status = nameserver_remotenotify_destroy();
616
pr_err("sysmgr_destroy : "
617
"nameserver_remotenotify_destroy "
618
"failed [0x%x]\n", status);
620
sysmgr_state.nameserver_remotenotify_init_flag \
625
/* Finalize Notify Ducati Driver module */
626
if (sysmgr_state.notify_ducatidrv_init_flag == true) {
627
status = notify_ducatidrv_destroy();
629
pr_err("sysmgr_destroy : "
630
"notify_ducatidrv_destroy failed [0x%x]\n",
633
sysmgr_state.notify_ducatidrv_init_flag = false;
637
/* Finalize MessageQTransportShm module */
638
if (sysmgr_state.messageq_transportshm_init_flag == true) {
639
status = messageq_transportshm_destroy();
641
pr_err("sysmgr_destroy : "
642
"messageq_transportshm_destroy failed [0x%x]\n",
645
sysmgr_state.messageq_transportshm_init_flag = \
650
/* Finalize ListMPSharedMemory module */
651
if (sysmgr_state.listmp_sharedmemory_init_flag == true) {
652
status = listmp_sharedmemory_destroy();
654
pr_err("sysmgr_destroy : "
655
"listmp_sharedmemory_destroy failed [0x%x]\n",
658
sysmgr_state.listmp_sharedmemory_init_flag = \
663
/* Finalize HeapBuf module */
664
if (sysmgr_state.heapbuf_init_flag == true) {
665
status = heapbuf_destroy();
667
pr_err("sysmgr_destroy : heapbuf_destroy "
668
"failed [0x%x]\n", status);
670
sysmgr_state.heapbuf_init_flag = false;
674
/* Finalize MessageQ module */
675
if (sysmgr_state.messageq_init_flag == true) {
676
status = messageq_destroy();
678
pr_err("sysmgr_destroy : messageq_destroy "
679
"failed [0x%x]\n", status);
681
sysmgr_state.messageq_init_flag = false;
685
/* Finalize GatePeterson module */
686
if (sysmgr_state.gatepeterson_init_flag == true) {
687
status = gatepeterson_destroy();
689
pr_err("sysmgr_destroy : "
690
"gatepeterson_destroy failed [0x%x]\n", status);
692
sysmgr_state.gatepeterson_init_flag = false;
696
/* Finalize NameServer module */
697
if (sysmgr_state.nameserver_init_flag == true) {
698
status = nameserver_destroy();
700
pr_err("sysmgr_destroy : nameserver_destroy "
701
"failed [0x%x]\n", status);
703
sysmgr_state.nameserver_init_flag = false;
707
/* Finalize Notify module */
708
if (sysmgr_state.notify_init_flag == true) {
709
status = notify_destroy();
711
pr_err("sysmgr_destroy : sysmgr_destroy "
712
"failed [0x%x]\n", status);
714
sysmgr_state.notify_init_flag = false;
718
/* Finalize SharedRegion module */
719
if (sysmgr_state.sharedregion_init_flag == true) {
720
status = sharedregion_destroy();
722
pr_err("sysmgr_destroy : "
723
"sharedregion_destroy failed [0x%x]\n", status);
725
sysmgr_state.sharedregion_init_flag = false;
729
/* Finalize ProcMgr module */
730
if (sysmgr_state.proc_mgr_init_flag == true) {
731
status = proc_mgr_destroy();
733
pr_err("sysmgr_destroy : proc_mgr_destroy "
734
"failed [0x%x]\n", status);
736
sysmgr_state.proc_mgr_init_flag = false;
740
/* Finalize MultiProc module */
741
if (sysmgr_state.multiproc_init_flag == true) {
742
status = multiproc_destroy();
744
pr_err("sysmgr_destroy : multiproc_destroy "
745
"failed [0x%x]\n", status);
747
sysmgr_state.proc_mgr_init_flag = false;
751
/* Finalize PlatformMem module */
752
if (sysmgr_state.platform_mem_init_flag == true) {
753
status = platform_mem_destroy();
755
pr_err("sysmgr_destroy : platform_mem_destroy "
756
"failed [0x%x]\n", status);
758
sysmgr_state.platform_mem_init_flag = false;
762
atomic_set(&sysmgr_state.ref_count, SYSMGR_MAKE_MAGICSTAMP(0));
766
pr_err("sysmgr_destroy : failed with "
767
"status = [0x%x]\n", status);
771
EXPORT_SYMBOL(sysmgr_destroy);
774
* ======== sysmgr_set_boot_load_page ========
776
* Function to set the boot load page address for a slave.
778
void sysmgr_set_boot_load_page(u16 proc_id, u32 boot_load_page)
780
struct sysmgr_boot_load_page *temp = \
781
(struct sysmgr_boot_load_page *) boot_load_page;
783
if ((proc_id < 0) || (proc_id >= MULTIPROC_MAXPROCESSORS)) {
785
"sysmgr_set_boot_load_page failed: Invalid proc_id passed\n");
789
/* Initialize the host config area */
790
sysmgr_state.boot_load_page[proc_id] = temp;
791
temp->host_config.offset = -1;
792
temp->host_config.valid = 0;
798
* ======== sysmgr_wait_for_scalability_info ========
800
* Function to wait for scalability handshake value.
802
void sysmgr_wait_for_scalability_info(u16 proc_id)
804
VOLATILE struct sysmgr_boot_load_page *temp = NULL;
806
if ((proc_id < 0) || (proc_id >= MULTIPROC_MAXPROCESSORS)) {
807
pr_err("sysmgr_wait_for_scalability_info failed: "
808
"Invalid proc_id passed\n");
811
temp = sysmgr_state.boot_load_page[proc_id];
813
pr_err("sysmgr_wait_for_scalability_info: BF while temp->handshake:%x\n",
815
while (temp->handshake != SYSMGR_SCALABILITYHANDSHAKESTAMP)
817
pr_err("sysmgr_wait_for_scalability_info:AF while temp->handshake:%x\n",
820
/* Reset the handshake value for reverse synchronization */
826
* ======== sysmgr_wait_for_slave_setup ========
828
* Function to wait for slave to complete setup.
830
void sysmgr_wait_for_slave_setup(u16 proc_id)
832
VOLATILE struct sysmgr_boot_load_page *temp = NULL;
834
if ((proc_id < 0) || (proc_id >= MULTIPROC_MAXPROCESSORS)) {
835
pr_err("sysmgr_wait_for_slave_setup failed: "
836
"Invalid proc_id passed\n");
839
temp = sysmgr_state.boot_load_page[proc_id];
841
while (temp->handshake != SYSMGR_SETUPHANDSHAKESTAMP)
844
/* Reset the handshake value for reverse synchronization */