Commit fe897345 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

debugging, made generated lowlevel.c produce working image

parent ea7d60dc
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -893,7 +893,7 @@ class EzynqClk:


# reg  uart_clk_ctrl, offs=0x154 dflt:0x3f03 actual: 0xa02
# reg  uart_clk_ctrl, offs=0x154 dflt:0x3f03 actual: 0xa02
        if 'UART' in self.iface_divs:
        if 'UART' in self.iface_divs:
            print self.iface_divs['UART']
#            print self.iface_divs['UART']
            if self.iface_divs['UART']['PLL']=='ARM':     
            if self.iface_divs['UART']['PLL']=='ARM':     
                uart_srcsel= 2
                uart_srcsel= 2
            elif self.iface_divs['UART']['PLL']=='DDR':     
            elif self.iface_divs['UART']['PLL']=='DDR':     
+9 −1
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@ import ezynq_registers
import ezynq_ddrcfg_defs
import ezynq_ddrcfg_defs
import ezynq_feature_config
import ezynq_feature_config
import ezynq_ddriob_def
import ezynq_ddriob_def
import ezynq_slcr_clk_def
def set_random_bits(old,d,bits):
def set_random_bits(old,d,bits):
    data = 0
    data = 0
    mask = 0
    mask = 0
@@ -45,6 +46,13 @@ class EzynqDDR:
        self.ddrc_register_set=  ezynq_registers.EzynqRegisters(self.DDRC_DEFS,0,regs_masked,permit_undefined_bits)
        self.ddrc_register_set=  ezynq_registers.EzynqRegisters(self.DDRC_DEFS,0,regs_masked,permit_undefined_bits)
        self.ddriob_register_set=ezynq_registers.EzynqRegisters(self.DDRIOB_DEFS,0,regs_masked,permit_undefined_bits)
        self.ddriob_register_set=ezynq_registers.EzynqRegisters(self.DDRIOB_DEFS,0,regs_masked,permit_undefined_bits)
    
    
    def generate_command_queue_empty(self):
        # generate code to be included in u-boot for testing DDR command queue
        reg_set=  ezynq_registers.EzynqRegisters(ezynq_slcr_clk_def.SLCR_CLK_DEFS,0,[])
        reg_set.wait_reg_field_values('ddr_cmd_sta',  # DDR Command queue state
                                               (('cmd_q_empty',    0)), True) # 0 - no commands for DDRC are queued, 1 - commands pending
        return reg_set.get_register_sets(sort_addr=True,apply_new=True)
    
        
        
    def parse_parameters(self,raw_configs):
    def parse_parameters(self,raw_configs):
        self.features.parse_features(raw_configs)
        self.features.parse_features(raw_configs)
+2 −2
Original line number Original line Diff line number Diff line
@@ -699,11 +699,11 @@ SLCR_CLK_DEFS={ #not all fields are defined currently
                                   'FIELDS':{
                                   'FIELDS':{
                  'reserved':                 {'r':( 1,31),'d':0, 'c':'reserved'},
                  'reserved':                 {'r':( 1,31),'d':0, 'c':'reserved'},
                  'start_ref':                {'r':( 0, 0),'d':0, 'c':'1 - Start Refresh (self-clearing). Only needed if auto refresh is disabled in reg_ddrc_dis_auto_refresh'}}},
                  'start_ref':                {'r':( 0, 0),'d':0, 'c':'1 - Start Refresh (self-clearing). Only needed if auto refresh is disabled in reg_ddrc_dis_auto_refresh'}}},
      'ddr_cmd_sta':              {'OFFS': 0x618,'DFLT':0,'RO':'RW',
      'ddr_cmd_sta':              {'OFFS': 0x618,'DFLT':0,'RW':'RO',
                                   'COMMENTS':'DDR Command queue state',
                                   'COMMENTS':'DDR Command queue state',
                                   'FIELDS':{
                                   'FIELDS':{
                  'reserved':                 {'r':( 1,31),'d':0, 'c':'reserved'},
                  'reserved':                 {'r':( 1,31),'d':0, 'c':'reserved'},
                  'vmd_q_empty':              {'r':( 0, 0),'d':0, 'm':'R', 'c':'0 - no commands fro DDRC are queued, 1 - commands pending'}}},
                  'cmd_q_empty':              {'r':( 0, 0),'d':0, 'm':'R', 'c':'0 - no commands for DDRC are queued, 1 - commands pending'}}},
      'ddr_urgent_sel':           {'OFFS': 0x61c,'DFLT':0,'RW':'RW',
      'ddr_urgent_sel':           {'OFFS': 0x61c,'DFLT':0,'RW':'RW',
                                   'COMMENTS':'DDR Urgent select',
                                   'COMMENTS':'DDR Urgent select',
                                   'FIELDS':{
                                   'FIELDS':{
+30 −10
Original line number Original line Diff line number Diff line
@@ -330,14 +330,15 @@ void dump_ddrc_regs(void)
    def make_slcr_register_dump(self):
    def make_slcr_register_dump(self):
        self.sections.append('slcr_dump')
        self.sections.append('slcr_dump')
        self.cfile+='''/* Dump all SLCR */        
        self.cfile+='''/* Dump all SLCR */        
void dump_slxr_regs(void)
void dump_slcr_regs(void)
{
{
\tuart_dump_regs(0xf8000000, 0xf8000b74, 16);
\tuart_dump_regs(0xf8000000, 0xf8000b74, 16);
\tuart_puts("\\r\\n");
\tuart_puts("\\r\\n");
}


'''
'''
        
        
    def dci_calibration (self, reg_sets,ddr): #ddr is an instance of ezynq_ddr.EzynqDDR
    def dci_calibration (self, reg_sets):
        if len(reg_sets)==0:
        if len(reg_sets)==0:
            print 'No DCI calibration register data is provided, skipping generating dci_calibration()'
            print 'No DCI calibration register data is provided, skipping generating dci_calibration()'
            return
            return
@@ -346,11 +347,12 @@ inline void dci_calibration(void)
{
{
\t/* Toggle active-low DCI reset, initialize DCI calibration, wait for DONE */
\t/* Toggle active-low DCI reset, initialize DCI calibration, wait for DONE */
'''
'''
        self._add_reg_writes(reg_sets)
        self.cfile+='}\n\n'
        self.cfile+='}\n\n'
        self.sections.append('dci_calibration')
        self.sections.append('dci_calibration')




    def ddr_start (self, reg_sets,ddr): #ddr is an instance of ezynq_ddr.EzynqDDR
    def ddr_start (self, reg_sets):
        if len(reg_sets)==0:
        if len(reg_sets)==0:
            print 'No DDR start data is provided, skipping generating ddr_start()'
            print 'No DDR start data is provided, skipping generating ddr_start()'
            return
            return
@@ -362,6 +364,17 @@ inline void ddr_start(void)
        self.cfile+='}\n\n'
        self.cfile+='}\n\n'
        self.sections.append('ddr_start')
        self.sections.append('ddr_start')


    def ddrc_wait_empty_queue (self,reg_sets):
        if len(reg_sets)==0:
            print 'No DDR start data is provided, skipping generating ddrc_status()'
            return
        self.cfile+='''/* Verify there are no commands in DDRC queue pending */        
inline void ddrc_wait_queue_empty(void)
{
'''
        self._add_reg_writes(reg_sets)
        self.cfile+='}\n\n'
        self.sections.append('ddrc_status')


    def _cp_led(self,name):
    def _cp_led(self,name):
        led_cp=self.features.get_par_value_or_none(name)
        led_cp=self.features.get_par_value_or_none(name)
@@ -407,10 +420,10 @@ void lowlevel_init(void)
        self._cp_led('LED_CHECKPOINT_5') # After UART is programmed
        self._cp_led('LED_CHECKPOINT_5') # After UART is programmed
        
        
        if self.features.get_par_value_or_none('DUMP_SLCR_EARLY'):
        if self.features.get_par_value_or_none('DUMP_SLCR_EARLY'):
            self.cfile+='\tuart_puts("SLCR registers before DCI/DDR initialization\\r\\n")\n'
            self.cfile+='\tuart_puts("SLCR registers before DCI/DDR initialization\\r\\n");\n'
            self.cfile+='\tdump_slcr_regs(); /*Dump all SLCR registers before DCI/DDR initialization */\n'
            self.cfile+='\tdump_slcr_regs(); /*Dump all SLCR registers before DCI/DDR initialization */\n'
        if self.features.get_par_value_or_none('DUMP_DDRC_EARLY'):
        if self.features.get_par_value_or_none('DUMP_DDRC_EARLY'):
            self.cfile+='\tuart_puts("DDRC registers before DCI/DDR initialization\\r\\n")\n'
            self.cfile+='\tuart_puts("DDRC registers before DCI/DDR initialization\\r\\n");\n'
            self.cfile+='\tdump_ddrc_regs(); /*Dump all DDRC registers before DCI/DDR initialization */\n'
            self.cfile+='\tdump_ddrc_regs(); /*Dump all DDRC registers before DCI/DDR initialization */\n'
        self.cfile+='''/*
        self.cfile+='''/*
   Calibrate DDR DCI impedance and wait for completion
   Calibrate DDR DCI impedance and wait for completion
@@ -427,10 +440,10 @@ void lowlevel_init(void)
'''
'''
        self._cp_led('LED_CHECKPOINT_7') # After DDR is initialized
        self._cp_led('LED_CHECKPOINT_7') # After DDR is initialized
        if self.features.get_par_value_or_none('DUMP_SLCR_LATE'):
        if self.features.get_par_value_or_none('DUMP_SLCR_LATE'):
            self.cfile+='\tuart_puts("SLCR registers after DCI/DDR initialization\\r\\n")\n'
            self.cfile+='\tuart_puts("SLCR registers after DCI/DDR initialization\\r\\n");\n'
            self.cfile+='\tdump_slcr_regs(); /*Dump all SLCR registers after DCI/DDR initialization */\n'
            self.cfile+='\tdump_slcr_regs(); /*Dump all SLCR registers after DCI/DDR initialization */\n'
        if self.features.get_par_value_or_none('DUMP_DDRC_LATE'):
        if self.features.get_par_value_or_none('DUMP_DDRC_LATE'):
            self.cfile+='\tuart_puts("DDRC registers after DCI/DDR initialization\\r\\n")\n'
            self.cfile+='\tuart_puts("DDRC registers after DCI/DDR initialization\\r\\n");\n'
            self.cfile+='\tdump_ddrc_regs(); /*Dump all DDRC registers after DCI/DDR initialization */\n'
            self.cfile+='\tdump_ddrc_regs(); /*Dump all DDRC registers after DCI/DDR initialization */\n'
        self.cfile+='''/*
        self.cfile+='''/*
   Copy 3 pages of OCM from 0x00000.0x2ffff to DDR 0x4000000.0x402ffff
   Copy 3 pages of OCM from 0x00000.0x2ffff to DDR 0x4000000.0x402ffff
@@ -440,9 +453,8 @@ void lowlevel_init(void)
\twhile (s< ((int *)0x30000)) *d++=*s++;
\twhile (s< ((int *)0x30000)) *d++=*s++;


'''
'''
# CONFIG_EZYNQ_LED_CHECKPOINT_10 = OFF # Before relocation down to address 0
        self.cfile+='\tddrc_wait_queue_empty(); /* Wait no commands are pending in DDRC queue */\n'            
# CONFIG_EZYNQ_LED_CHECKPOINT_11 = ON  # After relocation down to address 0

# CONFIG_EZYNQ_LED_CHECKPOINT_12 = OFF # Before leaving lowlevel_init()
        self._cp_led('LED_CHECKPOINT_8') # Before relocation to DDR (to 0x4000000+ )
        self._cp_led('LED_CHECKPOINT_8') # Before relocation to DDR (to 0x4000000+ )
        self.cfile+='''/*
        self.cfile+='''/*
   Now jump to the same instruction in the DDR copy of the currently executed code in OCM
   Now jump to the same instruction in the DDR copy of the currently executed code in OCM
@@ -452,6 +464,8 @@ void lowlevel_init(void)
\tasm("add pc, pc, #0x4000000" );
\tasm("add pc, pc, #0x4000000" );


'''
'''
# seems some delay is needed before remapping DDR memory
        self.cfile+='\tddrc_wait_queue_empty(); /* seems some delay is needed here before remapping DDR memory */\n'            
        self._cp_led('LED_CHECKPOINT_9') # After relocation to DDR (to 0x4000000+ )
        self._cp_led('LED_CHECKPOINT_9') # After relocation to DDR (to 0x4000000+ )
        self.cfile+='''/*
        self.cfile+='''/*
   Remap DDR to zero, FILTERSTART
   Remap DDR to zero, FILTERSTART
@@ -479,6 +493,9 @@ void lowlevel_init(void)
\ts= (int *) 0x4000000;
\ts= (int *) 0x4000000;
\td= (int *) 0;
\td= (int *) 0;
\twhile (d < ((int *) 0x30000)) *d++=*s++;
\twhile (d < ((int *) 0x30000)) *d++=*s++;

\tddrc_wait_queue_empty(); /* Wait no commands are pending in DDRC queue */   

/*
/*
   Continue with the original low-level init, Now we have 2 copies of the code again,
   Continue with the original low-level init, Now we have 2 copies of the code again,
   currently executing somewhere above 0x4000000. But as soon as we will return
   currently executing somewhere above 0x4000000. But as soon as we will return
@@ -493,6 +510,9 @@ void lowlevel_init(void)
\t/* Urgent write, ports S2/S3 */
\t/* Urgent write, ports S2/S3 */
\twritel(0xC, &slcr_base->ddr_urgent);
\twritel(0xC, &slcr_base->ddr_urgent);
'''
'''
        if 'uart_xmit' in self.sections:
            self.cfile+='\tuart_wait_tx_fifo_empty(); /* u-boot may re-program UART differently, wait all is sent before getting there */\n'
#uart_wait_tx_fifo_empty() - add if u-boot debug is on
        self._cp_led('LED_CHECKPOINT_12') # Before leaving lowlevel_init()
        self._cp_led('LED_CHECKPOINT_12') # Before leaving lowlevel_init()
        self.cfile+='''/* Lock SLCR back after everything with it is done */
        self.cfile+='''/* Lock SLCR back after everything with it is done */
\tlock_slcr();
\tlock_slcr();
+16 −4
Original line number Original line Diff line number Diff line
@@ -354,7 +354,6 @@ if raw_config_value('CONFIG_EZYNQ_SKIP_DDR', raw_configs) is None:
    segments.append({'TO':len(reg_sets),'RBL':True,'NAME':'DDR0','TITLE':'DDR registers configuration'})
    segments.append({'TO':len(reg_sets),'RBL':True,'NAME':'DDR0','TITLE':'DDR registers configuration'})
else:
else:
    print 'Debug mode: skipping DDR-related configuration'
    print 'Debug mode: skipping DDR-related configuration'

#initialize clocks
#initialize clocks
# unlock slcr - it is locked by RBL, but attempt to unlock in RBL will fail (and hang the system)
# unlock slcr - it is locked by RBL, but attempt to unlock in RBL will fail (and hang the system)
reg_sets=clk.clocks_regs_setup(reg_sets,force)
reg_sets=clk.clocks_regs_setup(reg_sets,force)
@@ -405,6 +404,14 @@ if not led_debug_mio_pin is None:
    reg_sets_led=mio_regs.generate_led_off_on(led_debug_mio_pin)
    reg_sets_led=mio_regs.generate_led_off_on(led_debug_mio_pin)
    reg_sets.extend (reg_sets_led) # just to be listed, not to be loaded
    reg_sets.extend (reg_sets_led) # just to be listed, not to be loaded
    segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'LED','TITLE':'registers/data to turn on/off debug LED - listed out of sequence'})
    segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'LED','TITLE':'registers/data to turn on/off debug LED - listed out of sequence'})

#add code to check DDRC status (no commands in queue)    
reg_sets_ddrc_sta=ddr.generate_command_queue_empty()
reg_sets.extend (reg_sets_ddrc_sta) # just to be listed, not to be loaded
segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DDRC_STA','TITLE':'resgister to test DDRC comamnd queue status - listed out of sequence'})
    
    
    
#    def generate_led_off_on(self, mio_pin):
#    def generate_led_off_on(self, mio_pin):
#CONFIG_EZYNQ_LED_DEBUG=47 # toggle LED during boot
#CONFIG_EZYNQ_LED_DEBUG=47 # toggle LED during boot
#CONFIG_EZYNQ_BOOT_DEBUG
#CONFIG_EZYNQ_BOOT_DEBUG
@@ -504,9 +511,14 @@ if 'UART_XMIT' in segment_dict:
#if not u_boot.features.get_par_value_or_none('BOOT_DEBUG') is None:
#if not u_boot.features.get_par_value_or_none('BOOT_DEBUG') is None:
    
    
if 'DCI' in segment_dict: 
if 'DCI' in segment_dict: 
    u_boot.dci_calibration(reg_sets[segment_dict['DCI']['FROM']:segment_dict['DCI']['TO']],ddr)
    u_boot.dci_calibration(reg_sets[segment_dict['DCI']['FROM']:segment_dict['DCI']['TO']])
if 'DDR' in segment_dict: 
if 'DDR_START' in segment_dict: 
    u_boot.ddr_start      (reg_sets[segment_dict['DDR']['FROM']:segment_dict['DDR']['TO']],ddr)
    u_boot.ddr_start      (reg_sets[segment_dict['DDR_START']['FROM']:segment_dict['DDR_START']['TO']])
if 'DDRC_STA' in segment_dict: 
    u_boot.ddrc_wait_empty_queue(reg_sets[segment_dict['DDRC_STA']['FROM']:segment_dict['DDRC_STA']['TO']])
    
#segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DDRC_STA','TITLE':'resgister to test DDRC comamnd queue status - listed out of sequence'})
    
u_boot.make_lowlevel_init()
u_boot.make_lowlevel_init()
u_boot.output_c_file(args.lowlevel)
u_boot.output_c_file(args.lowlevel)
#print u_boot.get_c_file()
#print u_boot.get_c_file()
Loading